Java中equals()方法的行为

The behaviour of equals() method in Java

本问题已经有最佳答案,请猛点这里访问。

考虑下面的Java代码:

1
2
3
4
5
6
7
    Object a = new Integer(2);
    Object b = new Integer(2);
    System.out.println(a.equals(b));

    Object x = new Object();
    Object y = new Object();
    System.out.println(x.equals(y));

第一个打印语句打印true和第二个false

如果这是故意的行为,这有助于Java编程吗?

如果这不是故意行为,这是Java中的缺陷吗?


我将保留回答您的问题,但您应该知道,如果问题的目的是让您学习,而您的解决方案是询问StackOverflow,那么您会伤害到自己。旁白…

这种行为是故意的。

java.lang.Object上的默认equals()方法比较内存地址,这意味着所有对象都不同(只有两个对同一对象的引用会返回true)。

java.lang.Integer重写了这一点以比较Integer的值,因此两个不同的Integer都表示数字2比较相等。如果你用==代替,两种情况都会得到false

Java中的标准实践是重写EDCOX1×13的方法来返回具有相同逻辑值的对象的EDCOX1×7,即使它们是在不同的时间(或甚至不同的参数)创建的。如果你没有办法问,"这两个东西代表同一个值吗?",那么让对象代表数字就不太有用了。.

顺便说一下,这是一个切线,Java实际上为一个小值保存了一个EDCOX1×1个对象的缓存。所以有时你可能会得到两个Integer对象,即使是==操作符也会返回true,尽管你从两个不同的来源得到它们。您甚至可以得到对较大整数的行为与对较小整数的行为不同的代码,而无需让它查看整数值!


这是预期行为。

Object.equals()考虑对象标识(即一个对象只等于它本身),这是对一般对象唯一可以做的事情。

Integer重写方法以依赖整数值,因为具有相同值的两个整数对象在逻辑上是相等的。许多其他类也会覆盖equals(),因为它是标准API的核心机制,很多功能(例如在集合框架中)都依赖于它。

你为什么对这种行为感到困惑?大多数人只会被==操作符所迷惑,而不是这样(它的工作方式与Object.equals()类似)。


Java中的EDCOX1 OR 13方法提供了一个特定的目的:它确定对象在逻辑上是否相等,即它们的内容是否相同,无论在每个特定类的上下文中可能意味着什么。这与相同的对象形成对比:两个不同的对象在逻辑上可能是等效的。

回到您的例子,ab是表示同一逻辑实体的不同对象—2的整数值。它们为相同的概念建模——一个整数,具有相同值的整数彼此相同。因此,ab是相等的。

另一方面,xy对象并不代表同一逻辑实体(事实上,它们并不代表任何东西)。这就是它们既不相同也不等价的原因。


另请参见object.equals()文档。顺便说一下,考虑使用Integer.valueOf(2)而不是new Integer(2),因为它减少了内存占用。

最后一件有趣的事情是,Integer.valueOf(2)==Integer.valueOf(2)将返回true,但Integer.valueOf(2000)==Integer.valueOf(2000)将返回false,因为在第一种情况下,您将收到两次整数对象的相同实例(后面有缓存),但在第二种情况下不会,因为缓存仅用于-127到128之间的值。


当然,这是故意的。

当比较Integer对象时,如果它们的值(在您的情况下,1相等),equals返回true

应用于Object类型的不同对象,返回false

1
x.equals(x)

将返回true