Java类文件和方法绑定
我试图查看本田class的类文件,下面是主方法的字节码Java类文件和方法绑定,java,methods,Java,Methods,我试图查看本田class的类文件,下面是主方法的字节码 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'
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'
}
}
我希望#17解析为Bike.run而不是Honda.run,因为在编译时,父类中存在的run方法的信息是可用的。
这里发生了什么?基类可能会更改,而不会重新编译子类 要执行该方法,在运行时在何处声明
run()。(如果没有,您将得到NoSuchMethodError
)
如果编译器将#17定义为
Bike.run(),那么代码将过于依赖于Bike类。我猜想:为了支持热点交换#17 Honda.run是Bike.run的同义词。但是如果Honda.run的实现突然可用(没有JVM重启),那么字节码就不需要更改#17现在指向Honda.run实现,而不是Bike.run的同义词。因此,JVM的vtable被更新,而不是需要更新的字节码。因此,在运行时,当JVM到达第9行时,它找到invokevirtual并转到#17,看到它解析为Honda.run()
,并尝试查找run()
方法,当它没有找到它时,JVM开始在父类中搜索run()
方法?@cloud Yes。有关更多详细信息,请阅读的规范。
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
#17 = Methodref #1.#18 // newpackage/Honda.run:()V
#18 = NameAndType #19:#6 // run:()V