Java 指向基类的动态多态性引用

Java 指向基类的动态多态性引用,java,dynamic,Java,Dynamic,我需要澄清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 stat

我需要澄清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()
时,它会在boo 8中以
的形式给出输出。这是因为动态多态性在运行时检查对象类型以调用该方法。

现在,当打印f.a时,它打印3,因为变量在java中不能被重写,这称为隐藏。这就是为什么它显示基本变量值而不是子变量值

现在我的问题是f是基类的引用,它指向子类对象。那么
f.a
如何指向基变量幕后发生了什么?引用如何指向基类?


(我知道规则,但我想知道如何/为什么?

我不知道这是否超出了你所学的范围,但它就在这里。编译代码时,编译器生成JVM执行的字节码

行中
f.a
中对字段
Foo.a
的引用

System.out.println(f.a);
编译为

getfield      #6                  // Field Foo.a:I
其中
getfield
是哪个

获取对象objectref的字段值,其中字段为
通过恒定池索引(index1中的字段引用确定,这是因为您在问题中已经说明:

在Java中不能重写变量


因此,引用
f.a
在编译时是静态解析的,它将编译器带到
Foo.a
,这是
3

,因为变量不能被重写,并且您从基类中给出了引用,这就是为什么

print f.a = 3 
如果你这样申报

Bar f = new Bar();
现在您可以打印
f.a
的值,它会给您
8

print f.a = 3 
Bar f = new Bar();