考虑以下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));
第一个打印语句打印true
,第二个打印false
。
如果这是故意的行为,这有助于如何用Java编程?
如果这不是故意行为,这是Java中的缺陷吗?
答案 0 :(得分:27)
我将以保留方式回答您的问题,但如果问题的目的是让您学习并且您的解决方案是问StackOverflow,那么您应该知道自己正在伤害自己。除此之外......
此行为是故意的。
equals()
上的默认java.lang.Object
方法比较内存地址,这意味着所有对象彼此不同(只有两个对同一对象的引用将返回{{ 1}})。
true
会覆盖此项以比较java.lang.Integer
的值,因此两个不同的Integer
都代表数字2比较相等。如果您使用了Integer
,那么两种情况都会得到==
。
Java中的标准做法是覆盖false
方法,以便为具有相同逻辑值的对象返回equals
,即使它们是在不同时间创建的(或者即使有不同的参数)。如果你没有办法提问,那么让对象代表数字并不是很有用,“这两个东西代表相同的值吗?”。
顺便说一下,这是一个切线,Java实际上为小值保留了true
个对象的缓存。因此,有时您可能会获得两个Integer
个对象,即使Integer
运算符将返回==
,尽管您从两个不同的来源获取它们。您甚至可以获得对于较大整数而言行为不同于较小整数的代码,而不会查看整数值!
答案 1 :(得分:7)
这是预期的行为。
Object.equals()
考虑对象标识(即一个对象只等于它自己),这是你可以为通用对象做的唯一事情。
Integer
会覆盖依赖于整数值的方法,因为具有相同值的两个Integer对象在逻辑上相等。许多其他类也覆盖equals()
,因为它是标准API的核心机制,并且具有许多功能,例如在集合框架中取决于它。
为什么你对这种行为感到困惑?大多数人只会被==
运算符而不是表现得像(Object.equals()
)。
答案 2 :(得分:3)
Java中的equals
方法用于特定目的:它确定对象逻辑是否相等,即它们的内容是否相同,无论在每个特定的上下文中是什么意思类。这与相同的对象形成对比:两个不同的对象在逻辑上是等价的。
回到您的示例,a
和b
是表示同一逻辑实体的不同对象 - 整数值2
。它们对相同的概念建模 - 整数,具有相同值的整数彼此相同。因此,a
和b
是平等的。
另一方面,x
和y
对象不代表相同的逻辑实体(事实上,它们不代表任何东西)。这就是为什么它们既不相同也不等同。
答案 3 :(得分:0)
当然是有意的。
比较Integer
个对象时,如果equals
的值(在您的情况下为true
)相等,则1
会返回Object
。
应用于false
类型的不同对象,它会返回x.equals(x)
。
true
会返回{{1}}。
答案 4 :(得分:0)
另见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之间的值