Java中两个new的对象对==做比较可以返回true吗?

昨天去京东面试,一个面试官问我上面这个问题,我回答说不可以。他说通过什么equal,hashCode什么的,可以使两个new出来的对象用==比较可以返回true,他当时也没说明白是怎么做,有人知道是怎么做到的吗
关注者
95
被浏览
22191
Java对象最重要的特性是带有“身份”(identity)——所谓reference equals比较的就是对象身份。

Java语言规范(Java SE 8版)里有这样的描述:
Chapter 15. Expressions
15.9.4. Run-Time Evaluation of Class Instance Creation Expressions
...
The value of a class instance creation expression is a reference to the newly created object of the specified class. Every time the expression is evaluated, a fresh object is created.
关键点就是每次执行new表达式的时候,一定要保证生成新的对象(a fresh object),也就是说每次生成的新对象都要有自己的identity。
于是,下述表达式永远都必须返回false:
new Foo() == new Foo()
如果不返回false的话,那就是JVM的bug。事实上我们做JVM实现的时候对此也是必须特别小心,就算这个例子里两个Foo对象都没有逃逸,可以被完全标量替换,我们也还是得把这个==表达式的值计算为false。

要注意的是:这个语义跟GC可能会复用已死对象的空间没有任何矛盾之处,跟identity hash code可能冲突也没有任何矛盾之处。

JVM的GC确实可能会把已经死了的对象的空间回收回来,复用给后来新创建的对象。但已经死了的对象的identity就已经不可能再在程序中被感知了,就算它以前占用的空间被别的新对象所使用,这也不会导致Java的==运算符发生两个身份不同的对象返回true的情况。

至于identity hash code(java.lang.Object.hashCode() / java.lang.System.identityHashCode()),它按规范本来就只有最多32位,本来就是不可能保证完全不重复的去体现对象的身份的,所以规范特别说明了:
Object (Java Platform SE 8 )
...

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.)
“尽力”就好了。