Java中equals()方法的行为

请考虑以下Java代码:

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)); 

第一个print语句打印为true ,第二个打印语句为false

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

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

我将以保留方式回答您的问题,但如果问题的目的是让您学习并且您的解决方案是问StackOverflow,您应该知道自己正在伤害自己。 除此之外……

这种行为是故意的。

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

java.lang.Integer会覆盖它以比较Integer ,因此两个不同的Integer都表示数字2比较相等。 如果您使用==代替,则两种情况都会出错。

Java中的标准做法是覆盖equals方法,以便对具有相同逻辑值的对象返回true ,即使它们是在不同时间(或甚至使用不同的参数)创建的。 如果你没有办法提问,那么让对象代表数字并不是很有用,“这两个东西代表相同的值吗?”。

顺便说一句,这是一个切线,Java实际上为小值保留了Integer对象的缓存。 所以有时你可能得到两个Integer对象,即使你从两个不同的源获得它们,即使==运算符也会返回true 。 对于较大的整数,您甚至可以获得与对较小整数不同的代码,而不必查看整数值!

这是预期的行为。

Object.equals()考虑对象标识(即一个对象只等于它自己),这是你可以为通用对象做的唯一事情。

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

你为什么对这种行为感到困惑? 大多数人只是被==运算符混淆而不是那样(它的作用类似于Object.equals() )。

Java中的equals方法用于特定目的:它确定对象在逻辑上是否相等,即它们的内容是否相同,无论在每个特定类的上下文中可能意味着什么。 这与对象相同 :两个不同的对象在逻辑上是等价的。

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

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

当然是故意的。

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

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

 x.equals(x) 

会回归true

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

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