Java中equals()方法的行为

时间:2012-02-14 13:36:07

标签: java

考虑以下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中的缺陷吗?

5 个答案:

答案 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方法用于特定目的:它确定对象逻辑是否相等,即它们的内容是否相同,无论在每个特定的上下文中是什么意思类。这与相同的对象形成对比:两个不同的对象在逻辑上是等价的。

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

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

答案 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之间的值