5

我学到了很多关于 C++ 如何在存在继承(多重、虚拟等)的情况下管理其虚拟表以及它如何将对象放置在内存中。

现在,Java 只需要担心单行继承,没有实例方法隐藏等,因此在这种情况下虚拟表应该更简单一些。我知道Class文件充当方法区域的“网关”,其中存储类型定义,包括我认为的方法字节码。我想到以下两个问题:

  1. Java中是否有任何vtable/method表结构?它是如何存储和链接到Class对象的?
  2. 继承/动态方法调用如何解决?我的意思是:

具有以下类和实例:

class A{ int f(){...} }
class B extends A{ int f(){...} }

A a = new B();
a.f();

调用 B 中的 f()。A 通过 B 的文件解析Class正确的方法指针吗?

非常感谢您的评论。

4

3 回答 3

4

在 Java 中,只指定了它必须做什么,没有指定它是如何做的。这有一些优点,因为可以以 C++ 不允许的方式优化代码。例如,“虚拟”方法可以由 JVM 内联,即使它们来自不同的库/jar。

于 2012-04-19T10:03:24.973 回答
4

调用a.f()在 java 字节码汇编语言中实现为:

aload_1 // load the local variable a, here from local address 1
invokevirtual with index into the constant pool for
    method ref:
        class "A"
        nameAndType "f", "()I"

在运行时,vtable 可能会解决对 Bf() 的调用。但正如您所见,类格式非常抽象,JVM 可以完全自由地加载类以实现“高效”实现。

于 2012-04-19T10:26:37.973 回答
3

是一个相关问题,其中包含正确链接的答案。需要注意的一点是,在我引用的 SO 问题中没有明确说明,Java 中的所有方法都是隐式虚拟的。如果对技术细节感到好奇,请查看jvm.h(搜索字符串“vtable”)。

于 2012-04-19T10:02:10.637 回答