在整数对象的情况下,==和equal在Java中如何工作?

时间:2018-07-01 07:55:07

标签: java hashcode

我发现了许多可能的重复问题,但没有一个人澄清我对其工作方式的怀疑?

    Integer a =25654; // a.hashCode()=>25654
    Integer b =25654; // b.hashCode()=>25654
    System.out.println(a.equals(b)); => true
    System.out.println(a == b);   => false

我已经在某处阅读了此答案。

  

如果没有父类提供重写,则它将默认使用最终父类Object中的方法,因此将剩下Object#equals(Object o)方法。根据对象API,这与==相同;也就是说,当且仅当两个变量都引用相同的对象且引用相同且相同时,它才返回true。因此,您将测试对象相等性而不是功能相等性。

在这种情况下,两个对象都具有相同的内存地址(按照哈希码),但是为什么我们在使用==比较时返回false?还是实际的内存地址不同?如果我错了,请纠正我。谢谢

2 个答案:

答案 0 :(得分:2)

Object.hashCode:

  

由类 Object 定义的hashCode方法的确返回不同   不同对象的整数。

但是Integer.hashCode会覆盖Object.hashCode

  

返回此对象的哈希码值,等于原始int   此Integer对象表示的值。

这意味着具有相同hashCode的整数不必共享同一对象。


Integer.hashCode

的源代码
@Override
public int hashCode() {
    return Integer.hashCode(value);
}

public static int hashCode(int value) {
    return value;
}

如果您愿意:

Integer a = 127;
Integer b = 127; 
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true

这是因为可以缓存[-128,127]之间的整数。

答案 1 :(得分:1)

  

在这种情况下,两个对象都具有相同的内存地址(根据哈希码)   仍然为什么当我们使用==比较时返回false?或者   实际的内存地址不同吗?如果我错了,请纠正我。   谢谢

  1. 哈希码不必视为内存地址,因为对象的内部地址可能会随时间变化。

  2. hashCode()的规范从不声明具有相同哈希码值的两个对象必然引用同一对象。
    equals而言,甚至两个具有相同哈希码的对象也可能不是Object.equals()

但是规范指出:

  

如果根据equals(Object)方法两个对象相等,则   在两个对象中的每个对象上调用hashCode方法必须产生   相同的整数结果。

在您的示例中这是可验证的:

Integer a =25654; // a.hashCode()=>25654
Integer b =25654; // a.hashCode()=>25654
System.out.println(a.equals(b)); => true

ab指的是equals()的对象,是的,它们的哈希码确实相同。


您的引用不是引用hashCode(),而是引用默认的Object.equals()方法,如果没有对equals()进行覆盖,则将使用该方法。

例如,如果我不为Foo类重写equals()和hashCode():

Foo fooOne = new Foo(1);
Foo fooOneBis = new Foo(1);
fooOne.equals(fooOneBis); // return false

这两个对象具有相同的状态,但是它们不等于使用Object.equals()来比较对象本身而不是它们的状态。

实际上equal()仅在变量引用相同的对象时才返回true:

Foo foo = new Foo(1); 
foo.equals(foo); // return true