我有以下测试程序。我创建了3个Integer
引用。我创建了2个Integer
个对象,并使引用i1和i2分别引用它们。我使参考i3等于i1。现在i1 equals()i3显然应该是真的,因为它们都引用堆上的相同对象。但为什么i1应该与i2相等?他们引用了两个不同的对象。我错过了什么。
public boolean equals(Object obj) Indicates whether some other object is "equal to" this one.
public class Test{
public static void main(String [] args)
{
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
Integer i3 = i1;
if(i1.equals(i3)) // UNDERSTANDABLE
System.out.println("equal");
if(i1.equals(i2)) // prints equal. WHY !!!!!
System.out.println("equal");
}
}
答案 0 :(得分:12)
包装类型的equals()
方法测试值相等性,如果要测试引用相等性,请改用==
,例如
System.out.println(new Integer(1) == new Integer(1));
答案 1 :(得分:5)
equals
是相等的值版本。类重写此方法以定义值相等意味着什么。例如,要查看两个字符串是否包含相同的字符序列,请使用.equals()
方法。如果要创建自己的类,并且例如要将其添加到HashMap
,则必须同时定义hashCode()
和equals()
方法才能使其正常工作。
要查看两个引用是否指向同一个内存位置,请使用==
。
答案 2 :(得分:4)
因为i1和i2具有相同的值。 Integer.equals()实现如下:
public boolean equals(Object obj) {
return (obj instanceof Integer
&& intValue() == ((Integer) obj).intValue());
}
所以i1和i2是整数,它们具有相同的值,因此它将返回true。
答案 3 :(得分:3)
Integer类的equals方法比较Integer包装的int值。当10等于10时,i1和i2被认为是相等的。
答案 4 :(得分:3)
通过查看Integer类,您可以更好地了解原因。以下是代码
/**
* Compares this object to the specified object. The result is
* <code>true</code> if and only if the argument is not
* <code>null</code> and is an <code>Integer</code> object that
* contains the same <code>int</code> value as this object.
*
* @param obj the object to compare with.
* @return <code>true</code> if the objects are the same;
* <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
答案 5 :(得分:2)
这是equals()
中Integer
的实施:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
考虑到这一点,如果i1的value
为10,而i2的value
也为10,则10 == 10将返回true。
答案 6 :(得分:2)
如果您在JavaDoc中进一步阅读,它会提供更多详细信息,特别是:
指示是否有其他对象 “等于”这个。等于 方法实现了等价 非空对象的关系 参考文献:
- 它是自反的:对于任何非空引用值x,x.equals(x)应该是 返回true。
- 它是对称的:对于任何非空参考值x和y,x.equals(y) 应该返回true,当且仅当 y.equals(x)返回true。
- 它是传递性的:对于任何非空参考值x,y和z,if x.equals(y)返回true和 y.equals(z)返回true,然后 x.equals(z)应该返回true。
- 一致:对于任何非空引用值x和y,为多个 调用x.equals(y) 一贯回归真实或 如果没有,则一直返回虚假 用于等比较的信息 在对象上进行了修改。
- 对于任何非空引用值x,x.equals(null)应返回false。
具体而言,由“equals(Object)”的实现者决定两个对象是否“相等”。为了参考比较,我们使用==
运算符,正如其他人所指出的那样。
如果您对此(及其他类似)主题感兴趣,我也建议您阅读Effective Java。
答案 7 :(得分:1)
你的问题的答案已经说过,但我有一个说明。要小心,因为你自己的对象是从Object扩展的,并且方法equal()
像操作符==
一样实现,所以如果你想比较值,你必须覆盖它。
答案 8 :(得分:1)
另请注意,“使用new Integer(int)
保证始终生成新对象,而Integer.valueOf(int)
允许由编译器,类库或JVM完成值的缓存。使用缓存值避免对象分配,代码会更快。“ - FindBugs
比较这些陈述:
System.out.println("new == " + (new Integer(1) == new Integer(1)));
System.out.println("new equals() " + new Integer(1).equals(new Integer(1)));
System.out.println("valueOf() == "
+ (Integer.valueOf(1) == Integer.valueOf(1)));
System.out.println("valueOf() equals() "
+ Integer.valueOf(1).equals(Integer.valueOf(1)));
产生此输出的:
new == false new equals() true valueOf() == true valueOf() equals() true
答案 9 :(得分:1)
它们具有相同的价值,这就是为什么它是真的。通常,equals方法不测试引用是否相等,尽管这是默认行为。