【发布时间】:2018-12-14 08:13:17
【问题描述】:
public class Bike {
void run() {
System.out.println("bike is running");
}
}
public class Honda extends Bike{
public static void main(String[] args) {
Honda h = new Honda();
h.run(); // output 'bike is running'
}
}
我尝试查看 Honda 类的类文件,下面是 main 方法的字节码
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #1 // class newpackage/Honda
3: dup
4: invokespecial #16 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #17 // Method run:()V
12: return
在第 9 行指定了要调用的方法,常量池中的 #17 条目解析如下
#17 = Methodref #1.#18 // newpackage/Honda.run:()V
#18 = NameAndType #19:#6 // run:()V
我期待 #17 解析为 Bike.run 而不是 Honda.run,因为在编译时,父类中存在 run 方法的信息是可用的。 这里发生了什么?
【问题讨论】:
-
我的猜想:支持 HotSpot 交换 #17 Honda.run 是 Bike.run 的同义词。但是,如果突然可以使用 Honda.run 的实现(无需重新启动 JVM),则不需要更改字节码。 #17 现在指向 Honda.run 实现,而不是 Bike.run 的同义词。所以更新了JVM的vtable,而不是需要更新的字节码。