2012-04-19 84 views
4

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

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

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

具有以下类和实例:B中

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

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

F()被调用。 B通过Class文件解析正确的方法指针?

非常感谢您的意见。

回答

3

a.f()该呼叫被在Java字节码汇编语言为实现。 但正如您所看到的,类格式非常抽象,并且JVM可以自由地为“高效”实现加载类。

+0

当然。我认为解决方案在运行时会使用B的'Class'文件并从那里加载方法,这就是为什么B.f()被调用 – Bober02 2012-04-19 10:34:35

3

Here是一个相关的问题,其中包含正确的链接。有一件事需要注意,这在我引用的SO问题中没有明确表达,即Java中的所有方法都是隐式虚拟的。如果对技术细节感兴趣,请查看jvm.h(搜索字符串“vtable”)。

3

在Java中,只有指定它必须做的事情,它是如何做的不是。这有一些优点,可以通过C++不允许的方式对代码进行优化。例如,即使虚拟机来自不同的库/ jar,“虚拟”方法也可以由JVM内联。

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" 

在运行时可能V表然后解决调用B.f():

+0

好的,你知道的任何可能的解决方案都是成功的吗? SUN如何做到这一点? – Bober02 2012-04-19 10:04:05

+1

我会说a)你不需要知道b)它可以在任何时候改变,所以你不会想要在某个特定的实现上建立一个解决方案。在C++编译完代码后,你知道它不会改变,但在Java中并非如此,甚至在程序运行时也会改变。 – 2012-04-19 10:06:34