当我们有两个班级时:
https://cdn.example.com
和:
class Foo {
void foo() {
System.out.println("foo");
}
}
Bar clazz对象是否在vtable中存储对foo()和bar()方法的引用,还是在Bar vtable中仅对bar()方法的引用,并且要访问foo()方法jvm访问Bar clazz对象,然后是Foo clazz对象,然后在其vtable中找到foo()方法? 它更像这样: 或者那个: 或者也许这没有在规范中描述,并且可能取决于JVM的实现?
答案 0 :(得分:4)
JVM规范没有规定如何实现虚拟方法调用。它甚至没有提到 vtable 的概念。 JVM实现可以选择这种方式或其他方式,只要它的行为符合预期即可。
对于Java SE虚拟机的参考实现HotSpot JVM,它的工作原理与您的第一幅图类似,即,一个类的单个vtable包含其所有虚拟方法,包括继承的虚拟方法。
------------------ ------------------
| Foo.class vtable | | Bar.class vtable |
|------------------| |------------------|
| clone | | clone | \
| equals | | equals | | java.lang.Object
| hashCode | | hashCode | / virtual methods
| ... | | ... |
| foo | | foo | } Foo virtual methods
------------------ | bar | } Bar virtual methods
------------------
这种布局可确保Foo
类的所有后代在vtable中的同一索引处都具有对foo
方法的引用。这样一来,即使是使用巨形方法,也可以在固定时间内进行足够快的虚拟调用。