Java 这些参考资料真的一样吗?
假设我们有以下代码段:Java 这些参考资料真的一样吗?,java,Java,假设我们有以下代码段: Cat cat = new Cat(); // The Cat class extends Animal ArrayList<Animal> animalList = new ArrayList<>(); animalList.add(cat); Cat=new Cat();//猫是动物的一类 ArrayList animalList=新的ArrayList(); 动物学家。添加(猫); cat是类型为cat的引用,指向类型为cat anim
Cat cat = new Cat(); // The Cat class extends Animal
ArrayList<Animal> animalList = new ArrayList<>();
animalList.add(cat);
Cat=new Cat();//猫是动物的一类
ArrayList animalList=新的ArrayList();
动物学家。添加(猫);
cat
是类型为cat
的引用,指向类型为cat
animalList.get(0)
是类型为Animal
的引用,它指向与cat引用相同的对象cat==animalList.get(0)
将计算为true
,因为它们都指向同一个对象因此,是的,编译器对引用(或者更准确地说:*变量)的“不同”有一定的理解(不能在
Animal
引用上调用Cat方法)。但在运行时,这一部分完全消失了。然后我们只是比较印在“卡片”上的“地址”。这是多态性的魔力(动态多态性)
实际对象是在运行时而不是编译时确定的
所以事实上猫和动物是一样的(猫),指的是相同的记忆
请在本文中查看更多详细信息
它解释得很好
我说这些引用并不完全相等,即使它们指向同一个内存位置,这是错的吗
是的,你错了。引用实际上只是一个内存位置
看起来您正在考虑将变量的类型作为引用的一部分,而实际上不是
那么,我说引用并不完全相等,即使它们指向相同的内存位置,这是不是错了
对。它们是同一块内存/实例,因此内存中没有任何变化(它保持在相同的内存位置)。在代码中将猫
视为动物
时,没有任何差异或信息丢失。但是,由于选择将对象视为动物
,因此只能获取动物的属性。如果您还想获得Cat
的详细信息,您可以强制转换对象。整个过程只发生在代码编译的预处理过程中
有关铸造和这种工作方式的更多信息,请参见此处:这是同一个对象。但是,如果cat有一个animal没有的方法miaow(),我想编译器不会允许您编写animalList.get(0).miaow(),因为在compiletime,它不知道在那个位置有一只cat,在对象上使用==
是一个内存引用比较,实际上它们都指向同一个内存位置。另请参见:重写equals()
和hashCode()
方法。谢谢!最后一段是我感到困惑的真正原因,编译时和运行时的解释很有意义:)“编译器对引用的“不同”有一定的理解”“我不会这样说。编译器知道变量是不同的。