这些引用真的一样吗?

时间:2018-10-10 13:52:40

标签: java

假设我们有以下代码段:

Cat cat = new Cat(); // The Cat class extends Animal

ArrayList<Animal> animalList = new ArrayList<>();
animalList.add(cat);
  1. cat是类型Cat的引用,指向类型为Cat的对象

  2. animalList.get(0)是类型Animal的引用,它与cat引用指向相同的对象。

  3. cat == animalList.get(0)将计算为true,因为它们都指向同一个对象。

但是,一个引用的类型为Cat,而另一个引用的类型为Animal(列表中的位置0),所以我错误地指出引用即使指向也并不完全相等到相同的内存位置?我是否过多地研究术语?

4 个答案:

答案 0 :(得分:5)

现有的answer在房屋周围使用了一个很好的类比,将引用描述为“地址”,使您可以找到“房屋”(代表实例对象的房屋)。

如果您扩展这种想法,可以说可以在不同卡上打印地址。因此,这些卡外观不同,但它们上打印的地址始终相同。

是的,编译器对引用(或更确切地说是**变量)具有“不同”的理解(您不能在{{1上调用Cat方法}}参考)。但是在运行时,该部分已完全消失。然后,我们只比较印在“卡片”上的“地址”。

答案 1 :(得分:3)

  

我说引用不是完全相等是错误的,即使它们指向相同的内存位置?

是的,你错了。引用实际上是只是一个内存位置。

似乎您正在考虑将变量的类型作为引用的一部分,但实际上不是。

答案 2 :(得分:1)

这是多态(动态多态)的魔力。

实际对象是在运行时确定的,而不是在编译时确定的。

所以实际上猫和动物是相同的(猫),并且引用相同的内存。

请在本文中查看更多详细信息

http://ocpj8.javastudyguide.com/ch02.html

解释得很好。

答案 3 :(得分:1)

  

所以我说引用不完全相等是错误的,即使它们指向相同的内存位置?

是的。它们是同一段内存/实例,因此您的内存中没有任何变化(它保持在相同的内存位置)。将Cat视为代码中的Animal时,没有任何区别或信息丢失。但是,由于您选择将对象视为Animal,因此您只能获得Animal的属性。如果您还想获得Cat的详细信息,则只需投射对象即可。这整个过程仅在代码编译的预处理中发生。

有关铸造和这种工作方式的更多信息,请参见:How does Java Object casting work behind the scene?