比较对象内存地址,Java

比较对象内存地址,Java,java,object,boolean,Java,Object,Boolean,所以这个程序打印的是假的,但我想它打印的是真的。它询问r1的内存地址是否与r2相同。r1等于r2,然后r2变为r3,但这不重要,对吧?我们还在比较r2 让我们看看每次作业后的情况 Robot r1,r2,r3; r1=new Robot("Huey",2,3); r2=new Robot("Louie",5,4); r3=new Robot("Louie",5,4); r1=r2; r2=r3; r3=r1; System.out.print(r1==r2); 最后,r1是第一个“路易”实例(

所以这个程序打印的是假的,但我想它打印的是真的。它询问r1的内存地址是否与r2相同。r1等于r2,然后r2变为r3,但这不重要,对吧?我们还在比较r2

让我们看看每次作业后的情况

Robot r1,r2,r3;
r1=new Robot("Huey",2,3);
r2=new Robot("Louie",5,4);
r3=new Robot("Louie",5,4);
r1=r2;
r2=r3;
r3=r1;
System.out.print(r1==r2);
最后,
r1
是第一个“路易”实例(前一个是
r2
),而
r2
是第二个


PS我假设我不需要注释为什么
新机器人(“Huey”,2,3)==新机器人(“Huey”,2,3)
返回false。

您正在比较两个不同的机器人对象。使用必须在Robot类中重新定义的相等项。

通过

// r1 - Huey, r2 - Louie1, r3 - Louie2
r1=r2;
// r1 - Louie1, r2 - Louie1, r3 - Louie2
r2=r3;
// r1 - Louie1, r2 - Louie2, r3 - Louie2
r3=r1;
// r1 - Louie1, r2 - Louie2, r3 - Louie1

r1==r2吗?r1是Louie#1,r2是Louie#2

您可以将代码片段可视化为:

r1 = Huey
r2 = Louie#1
r3 = Louie#2

r1 = Louie#1
r2 = Louie#2
r3 = Huey

显然,在结尾处,
r1
r2
并不是指同一个对象,因此比较它们会得到
false

不,指向对象的变量是引用。执行r1=r2时,r1指向r2指向的同一对象,r2=r3后,r2指向r3指向的同一对象。因此,您正在比较第二个机器人对象的内存地址和第三个机器人对象的内存地址,它们是不同的。如果您想要语义均衡,您的Robot类必须重写equals()和hashCode(),请查看:

In
r1=newrobot(“Huey”,2,3)行内存管理器从堆中获取一些内存(例如,它是M1内存)并在那里写入
Robot(“Huey”,2,3)
。r1表示M1

r2=新机器人(“路易”,5,4)行内存管理器从堆中获取一些内存(例如,它是M2内存)并在那里写入
Robot(“Louie”,5,4)
。r2表示M2

最后在
r3=新机器人(“路易”,5,4)行内存管理器从堆中获取一些内存(例如,它是M3内存)并在那里写入
Robot(“Louie”,5,4)
。r3表示M3

r1=r2
之后,命令r1表示M2。在
r2=r3
之后,命令r2表示M3。在
r3=r1
之后,命令r2表示M2


当您编写
System.out.print(r1==r2)
时,它会尝试比较r1和r2所指的内容,即M2和M3。这就是它返回false的原因。

哦,好的,很好,所以我要这样分解它。现在,当你在评论r1-Louie1中看到r1指向Louie1时,你会认为这是正确的吗?@fprime是的,“points”在这里是个好词。即,
System.out.print(r1==r3)
应该打印
true
。我经常这样说,但如果您使用调试器逐步检查代码,这一点就很明显了。内存地址?JAVA实际上,
r1==r2
询问r1和r2是否都引用同一实例。
Initial        r1 -> Obj1, r2 -> Obj2, r3 -> Obj3

After r1=r2    r1 -> Obj2, r2 -> Obj2, r3 -> Obj3 ( Obj1 ready for GC)

After r2=r3    r1 -> Obj2, r2 -> Obj3, r3 -> Obj3

After r3=r1    r1 -> Obj2, r2 -> Obj3, r3 -> Obj2