用于 super 方法的 Java vtable

标签 java jvm dynamic-dispatch

当我们有两个类时:

class Foo {
    void foo() {
        System.out.println("foo");
    }
}

和:

class Bar extends Foo{
    void bar() {
        System.out.println("bar");
    }
}

Bar clazz 对象是否在 vtable 中存储对 foo() 和 bar() 方法的引用,还是在 Bar 的 vtable 中仅存储对 bar() 方法的引用并访问 foo() 方法 jvm 访问 Bar clazz 对象,然后 Foo clazz 对象然后在其 vtable 中找到 foo() 方法? 是不是更像这样: enter image description here 或者那个: enter image description here 或者也许这没有在规范中描述并且可以依赖于 JVM 实现?

最佳答案

JVM规范没有规定如何实现虚方法调用。它甚至没有引用vtable的概念。 JVM 实现可以选择这种方式或另一种方式,只要它的行为符合预期。

对于HotSpot JVM,Java SE虚拟机的引用实现,它的工作原理就像你的第一张图片一样,即一个类的单个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 方法。这使得虚拟调用足够快,即在恒定时间内,即使对于超态方法也是如此。

关于用于 super 方法的 Java vtable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53603269/

相关文章:

java - Android 抽象类坏魔法空指针

java - 写入 Excel 文件时会丢失一些数据。 java

java - 在浏览器中运行java-applet源代码

lambda - 如何将伪参数传递给 clojure lambdas?

c++ - 循环内不变多态类型的优化

C++ 或 D : idiom to decouple classes without dynamic dispatch?

Java将数据发送到初始化对象的类

java - twitter4j 和处理出现问题

JAVA_OPTS 用于增加堆大小

Smalltalk动态查找优化