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

Java方法表 我学到了很多关于C++如何在继承(多重、虚拟等)的情况下管理虚拟表的方法以及它如何在内存中放置对象。,java,jvm,virtual-machine,vtable,Java,Jvm,Virtual Machine,Vtable,现在,Java只需要担心单行继承,没有实例方法隐藏等问题,所以在这种情况下,虚拟表应该更简单一些。我知道Class文件充当方法区域的“网关”,在这里存储类型定义,我想包括方法字节码。我想到以下两个问题: Java中通常有vtable/method表结构吗?它是如何存储和链接到类对象的 继承/动态方法调用是如何解决的?我的意思是: 具有以下类和实例化: class A{ int f(){...} } class B extends A{ int f(){...} } A a = new B();

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

  • Java中通常有vtable/method表结构吗?它是如何存储和链接到
    对象的
  • 继承/动态方法调用是如何解决的?我的意思是:
  • 具有以下类和实例化:

    class A{ int f(){...} }
    class B extends A{ int f(){...} }
    
    A a = new B();
    a.f();
    
    B中的f()被调用。通过B的
    文件进行解析是否是正确的方法指针


    非常感谢您的评论。

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

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

    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可能会解决对B.f()的调用。
    但是正如您所看到的,类格式非常抽象,JVM可以自由地加载类以实现“高效”的实现。

    好的,您知道的任何可能的解决方案都是成功的吗?SUN是如何做到这一点的?我想说a)您不需要知道b)它随时都可能发生变化,因此您不希望将解决方案建立在特定的实现之上。在C++中,一旦编译了代码,你就知道它不会改变,在java中,它不是在程序运行时改变的。@ PeterLawrey,内联是什么意思?当然。我认为在运行时,解析将使用B的
    Class
    file并从那里加载方法,这就是为什么B.f()是called@Bober02这个答案和你的评论都只是关于第二个问题的推测,你没有确切提到B的f()实现是如何被选择的。@Sajuuk vtable,virtual method table,是C++中实现的术语,而不仅仅是语言。Java指定检查这个类。Java既不规定也不描述实现。参见@JoopEggen您是否建议不同的Java实现在实现vtable时几乎没有共同点?或者在没有提到具体实现的情况下讨论vtable实现是毫无意义的?