我需要澄清Java的动态多态性。
class Foo {
int a=3;
public void display() {
System.out.println(" in foo "+a);
}
}
class Bar extends Foo {
int a=8;
public void display() {
System.out.println(" in boo "+a);
}
}
public class Tester {
public static void main(String[]args) {
Foo f = new Bar();
f.display();
System.out.println(f.a);
}
}
在这里,当我创建具有基类引用的子类对象时,在调用方法
f.display()
时,它的输出为in boo 8
。这是因为动态多态性会在运行时检查对象类型以调用该方法。 现在在打印
f.a
时它会打印3,因为在Java中不能覆盖变量,这称为隐藏(hide),这就是为什么它显示基变量值而不是子变量值。现在我的问题是f是指向子类对象的基类的引用。然后
f.a
如何指向基本变量。 在幕后发生了什么?引用如何指向基类? (我知道规则,但我想知道为什么/为什么?)
最佳答案
我不知道这是否超出了您所学的范围,但事实确实如此。编译代码时,编译器会生成JVM执行的字节码。
该行中Foo.a
中对字段f.a
的引用
System.out.println(f.a);
被编译为
getfield #6 // Field Foo.a:I
其中
getfield
是a bytecode instruction,和恒定池
Constant pool:
// [...]
#6 = Fieldref #20.#24 // Foo.a:I
// [...]
因此,字节码引用的是
Foo
类(变量的声明类型)中的字段,而不是实例的运行时类类型中的字段。您可以使用以下命令查看生成的字节码
javap -c -v YourClass
关于java - 指向基类的动态多态引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22124122/