简体   繁体   English

什么 JVM 检查 Java 对象相等性 (==)?

[英]What JVM checks in Java object equality (==)?

What does the JVM check in object equality ( == )? JVM 在对象相等性 ( == ) 中检查什么? Is it the hashCode of two objects or something else?是两个对象的hashCode还是别的?

The == operator only checks reference equality. ==运算符检查引用相等性。 It doesn't call any methods on the object... it just checks whether the two references involved are equal, ie they refer to the same object.它不调用对象上的任何方法...它只是检查涉及的两个引用是否相等,即它们引用同一个对象。

In simple cases I believe this is just a matter of comparing the references in a bitwise fashion - checking whether or not they consist of the same bytes.在简单的情况下,我相信这只是按位方式比较引用的问题——检查它们是否由相同的字节组成。 For more complex environments (eg "compressed oops" ) there could be slightly more work involved, in order to compare different representations.对于更复杂的环境(例如“压缩的 oops” ),可能会涉及更多的工作,以便比较不同的表示。 But the internally reference is effectively a pointer of some kind, and it's just a matter of comparing the two pointers.但内部引用实际上是某种指针,只是比较两个指针的问题。

The == is used to compare object references. == 用于比较对象引用。 It simply checks if the two object are pointing to the same reference.它只是检查两个对象是否指向同一个引用。

The equality operator ( == ) test for reference equality not hashCode相等运算符 ( == ) 测试引用相等性而不是hashCode

public static void main(String[] args) {

    MyClass obj1=new MyClass();

    MyClass obj2=new MyClass();   //obj1 and obj2 refers two different location

    System.out.println("obj1= "+obj1+"\tobj2="+obj2);
    if(obj1==obj2){   // so return false.
        System.out.println("obj1==obj2");
    }else{
        System.out.println("obj1!=obj2");
    }

    System.out.println(obj1.hashCode()+"\t"+obj2.hashCode());

    }

class MyClass{}

output:输出:

obj1= com.think.test.MyClass@1e9cb75    obj2=com.think.test.MyClass@2c84d9
obj1!=obj2
hashCode
obj1=32099189   obj2=2917593

EDIT编辑

class EqualityTest {

     @Override
     public int hashCode(){ 
         return 1; 
     } 
     public static void main(String... arg){
         EqualityTest t1 = new EqualityTest(); 
         EqualityTest t2 =t1;  // t2 referring to t1.
         System.out.println(t1); 
         System.out.println(t2); 
         System.out.println(t1.hashCode());
         System.out.println(t2.hashCode()); 
         System.out.println(t1==t2);  // so it return true.
         } 
}

output:输出:

com.think.test.Test9@1
com.think.test.Test9@1
1
1
true

It is easy to see how JVM treats == at bytecode level.很容易看出 JVM 如何在字节码级别处理==

For example例如

public boolean compare(Object o1, Object o2)
{
     return o1 == o2;
}

compiles to the following byte code instructions (use javap -c to generate this):编译为以下字节码指令(使用javap -c生成):

public boolean compare(java.lang.Object, java.lang.Object);
  Code:
    0: aload_1
    1: aload_2
    2: if_acmpne     7
    5: iconst_1
    6: ireturn
    7: iconst_0
    8: ireturn

aload1 and aload2 load the references of o1 and o2 on the stack. aload1aload2在堆栈上加载 o1 和 o2 的引用。 The == operation is performed by if_acmpne . ==操作由if_acmpne执行。

if_acmpne pops the top two object references off the stack and compares them. if_acmpne 从堆栈中弹出顶部的两个对象引用并比较它们。 If the two object references are not equal (ie if they refer to different objects) , execution branches to.... If the object references refer to the same object, execution continues at the next instruction.如果两个对象引用不相等(即,如果它们引用不同的对象) ,则执行分支到...。如果对象引用引用相同的对象,则执行在下一条指令处继续。

Of course this doesn't tell you how the JVM interpreter implements object references, or how a bytecode to native compiler like Hotspot implements it, but its a good start to explore the topic.当然,这并没有告诉您 JVM 解释器如何实现对象引用,或者像 Hotspot 这样的本机编译器的字节码如何实现它,但它是探索该主题的良好开端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM