Java方法System.identityHashCode(...)在我使用 this 引用在内部调用它时为对象返回一个不同的值,而不是在相同的变量引用上调用它对象
class MyObject {
public void test(MyObject that){
LOGGER.info("this hash: {}",System.identityHashCode(this));
LOGGER.info("that hash: {}",System.identityHashCode(that));
LOGGER.info("equals: {}",this == that);
}
}
和测试...
MyObject o = new MyObject();
o.test(o);
和输出......
this hash: 263009111
that hash: 524075148
equals: false
会导致这种情况发生的原因是什么?有问题的真实对象是一个Hibernate实体,但是我已经将上面的测试直接添加到代码中,并且它在特定场景中显示了相同的行为。为什么对象使用 this 关键字显示与引用自身时不同的身份哈希码?我还通过设置对象的某些字段并确认本地字段设置为相同的值来确认引用是正确的。 因此,如果引用正确,为什么identityHashCode(...)返回两个不同的值,为什么“==”运算符失败?我的印象是这个方法是专门用于识别对同一逻辑对象的引用?
答案 0 :(得分:1)
它们是两个独立的对象(即使它们在概念上可能包含相同的数据),==
为假的事实证明了这一点。
System.identityHashCode()
返回与默认方法hashCode()返回的给定对象相同的哈希码,无论给定对象的类是否覆盖hashCode()。空引用的哈希码为零。
换句话说,标准hashCode
仅使用对象的地址。每个不同的对象都会给出不同的价值。这与hibernate无关,它是System.identityHashCode()
的工作原理。
如果你想要你期望的行为,那么在hibernate返回给你的对象上使用equals
和hashCode
方法。
你很可能会有某种树形结构:
this->A<-that
通过A
或this
对that
进行更改是通过引用可见的,但它们仍然是两个不同的java对象,即使它们包含相同的内部值。这很可能是用于支持延迟加载值等事情的hibernate代理对象。
要确认这一点,请在调试器中逐步执行此操作并查看实际对象。