我需要澄清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

其中getfielda bytecode instruction



和恒定池
Constant pool:
   // [...]
   #6 = Fieldref           #20.#24        //  Foo.a:I
   // [...]

因此,字节码引用的是Foo类(变量的声明类型)中的字段,而不是实例的运行时类类型中的字段。

您可以使用以下命令查看生成的字节码
javap -c -v YourClass

关于java - 指向基类的动态多态引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22124122/

10-12 00:21
查看更多