当前位置: 首页 > 面试题库 >

java接口如何在内部实现?(vtables?)

容飞掣
2023-03-14
问题内容

C
++具有多重继承。汇编级别的多重继承的实现可能非常复杂,但是在线上通常有很好的说明(vtable,指针修复,thunk等)。

Java没有多重实现继承,但是它确实具有多重接口继承,因此我认为每个类只有一个vtable的直接实现无法实现。java如何在内部实现接口?

我意识到与C++相反,Java是Jit编译的,因此不同的代码段可能会进行不同的优化,并且不同的JVM可能会做不同的事情。因此,是否有许多JVM遵循的一般策略,还是没有人知道特定JVM中的实现?

而且,JVM通常会取消虚拟化和内联方法调用,在这种情况下根本不涉及vtable或等效方法,因此询问实现虚拟/接口方法调用的实际组装顺序可能没有任何意义,但是我认为大多数JVM仍然保留一些如果周围的类无法将所有内容虚拟化,则可以使用这些类的一种通用表示形式。这个假设错了吗?这种表示形式看起来是否像C vtable?如果是这样,接口是否具有单独的vtable,这些接口如何与类vtable链接?如果可以的话,对象实例可以像C 中的对象实例一样具有多个vtable指针(指向类/接口vtable)吗?对同一个对象的类类型和接口类型的引用是否总是具有相同的二进制值,或者它们是否可以像在C++中那样需要指针修正的区别?

(供参考:这个问题询问有关CLR的问题,尽管现在可能已经过时,但该msdn文章中似乎有一个很好的解释。对于Java,我找不到任何类似的东西。)

编辑:

  • 我的意思是“实现”,意思是“ GCC编译器如何实现整数加法/函数调用/等等”,而不是“ Java类ArrayList实现List接口”。
  • 我知道这在JVM字节码级别上是如何工作的,我想知道的是JVM在完成加载类文件和编译字节码后生成了什么样的代码和数据结构。

问题答案:

HotSpot
JVM的关键功能是内联缓存。这实际上并不意味着要内联目标方法,而是意味着要在JIT代码中加入一个假设,即以后对虚拟方法或接口方法的每次调用都将以完全相同的实现为目标(即,调用站点是单态的)。在这种情况下,将检查是否编译成假设是否成立(即,目标对象的类型是否与上次相同),然后将控制权直接传递给目标方法-
不使用虚拟表参与其中。如果断言失败,则可以尝试将其转换为大形调用站点(即具有多种可能的类型);如果仍然失败(或者这是第一个调用),则使用vtables(用于虚拟方法)和itables(用于接口)执行常规的长时间查找。

编辑
:热点Wiki上有关于vtable和itable存根的更多详细信息。在多态情况下,它仍将内联缓存版本放入呼叫站点。但是,代码实际上是在vtable或itable中执行查找的存根。每个vtable偏移量(0、1、2,…)都有一个vtable存根。接口调用在给定偏移量查找可扩展对象(如果找到)之前,对可扩展对象数组进行线性搜索。



 类似资料:
  • 问题内容: 如何创建实现此接口的Clojure对象,然后从Java代码调用它? 问题答案: 是实现接口的首选- 重型,较旧且较慢,因此应尽可能避免。一个实现看起来像:

  • 问题内容: Java中的以下代码可正确编译: 而Scala中的此代码不: Java代码清单到Scala的正确翻译(如果存在)是什么? 欢迎对语言设计进行理论解释。 问题答案: 内部类型仅针对特征的特定实例实现定义。由于scala具有 依赖于路径的 类型,因此的每个实例将具有自己的子特性。 如果您需要一个接口来实现客户端的一般行为,并且不依赖于特定实例,则应在

  • 问题内容: 我不确定如何在我的抽象类中实现类似的接口。我有以下示例代码可用来尝试解决这个问题: 我有一个测试类,该类将创建Animal类型的对象,但是我希望在该类中具有一个可比的接口,以使发现的年纪高于低位。我不知道如何去解决这个问题。 问题答案: 您只需要定义即p。然后,您必须以自己喜欢的方式实现该方法。 使用的实现,具有较高级别的动物将获得更高的顺序。我希望你的想法和这个例子。

  • 我不确定如何在我的抽象类中实现一个可比较的接口。我有下面的示例代码,我正在使用它来尝试和得到我的头脑周围: 我有一个测试类,它将创建动物类型的对象,但是我想在这个类中有一个类似的接口,这样更早的发现排名就会更高。不过,我不知道该怎么做。

  • 问题内容: 我有一个关于在接口中放置Java枚举的问题。为了使其更清楚,请参见以下代码: 我知道一个接口由带有 空主体 的方法组成。但是,我在这里使用的枚举需要一个构造函数和一个方法来获取关联的值。在此示例中,建议的接口将不仅包含空主体的方法。是否允许这种实现? 我不确定是否应该将枚举类放入接口或实现此接口的类中。 如果将枚举放入实现此接口的类中,则方法public Number getNumbe

  • 我有一个关于在接口中放置Java枚举的问题。为了更清楚,请看下面的代码: 我知道一个接口由带有空主体的方法组成。但是,我在这里使用的枚举需要一个构造函数和一个方法来获取关联的值。在本例中,所建议的接口将不仅仅由具有空主体的方法组成。允许这种实现吗?