代码之家  ›  专栏  ›  技术社区  ›  Adelin

抽象类比java中的接口快吗?

  •  2
  • Adelin  · 技术社区  · 6 年前

    根据这篇文章 here ,在抽象类vs接口上,抽象类的速度比接口快一点,这是为什么,你能用jvm来解释使用接口vs抽象类的机制吗?

    4)Java抽象类与接口的第四个区别 抽象类比接口快一点是因为 接口在调用 爪哇。在大多数情况下,这并不是一个显著的差异,但是如果 您正在编写一个时间关键型应用程序,那么您可能不希望 不遗余力。

    2 回复  |  直到 6 年前
        1
  •  5
  •   Hemant Singh    6 年前

    在Java的早期,有一个技术上的原因造成了这种差异。你知道“虚拟表”或“vtbl”是什么吗?基本上,一个简单的vtbl可以用于直接继承的方法,因此jvm只需查看两个指针就可以找到从抽象类继承的方法的代码——这相对来说比较快。但是,由于任何类都可以实现任意数量的接口,因此查找实现接口方法的代码将涉及跟踪指向由类实现的接口表的指针,然后搜索该表以查找实现该接口的vtbl,然后在表中查找方法指针。这显然需要做更多的工作,所以调用接口方法的速度过去要慢得多。

    这些天,JVMs更聪明,而且大多数这种查找都是在动态编译期间完成的,所以运行时差异很小或者根本不存在。

        2
  •  3
  •   Holger    6 年前

    答案取决于实现细节,但在这种形式下,它是不正确的。事实上,作者已经试图通过稍微使用这个词来回避一个事实检查,以打开你从未观察到这种性能差异的可能性。

    详细说明 this answer ,这种语句背后的思想是,一个普通类有一个由子类继承的可重写方法(也称为“vtable”)表,子类可以在末尾添加新方法,并替换它们重写的方法的表条目。因此,第一个解析只需要找到可以记住的表索引,因此后续调用只需要调用该索引处实际接收方类的方法。

    由于接口可以由没有继承关系的不同类实现,因此实现方法可以位于这些类的不同表索引处。解决这个问题的一种方法是从接口表到实际的类表进行某种映射。假设这种双重分派导致了调用接口方法比普通方法慢的假设。

    但是,像hotspot jvm这样的jvm不使用这种双重分派。它们像任何其他虚拟方法调用一样,解析针对实际接收方类的接口方法调用。只要接收者是同一类层次结构的一部分,例如,您可以调用 Appendable 接口和接收器始终是 Writer 类,不需要其他步骤。对于大多数接口方法调用来说,这是相当有效的。

    有些情况下,接口方法调用将在不相关类的不同实现中结束,例如,当调用 可追加 有时最后 StringBuilder 其他时间 作家 ,但是,我们有一个无法比拟的场景。这个特定的调用可能比普通的方法调用稍慢,但是由于不可能用抽象类构造相同的场景,因此说它比在这里使用抽象类慢是没有任何意义的。

    对于与性能相关的代码部分(也称为热点),jvm将执行运行时优化,从而使这种技术差异变得无关紧要。即使是普通虚拟方法调用的微小开销通常也会被消除,因为后续的优化严重依赖于积极内联目标方法代码的能力,以便能够使用调用方上下文及其已知的周围条件来优化被调用方代码。