10

这是在声明如下对象时使用接口/基类引用的一般编码实践:

InterfaceIF ref = new SomeObject();

我知道这提供了松散耦合,我们可以在不影响太多代码的情况下更改/编写具有新实现的新类。

这在这里也得到了很好的解释。

但是我试图无法理解并且没有回答问题的一件事是:

  • 使用接口/基类引用是否会影响性能。
  • 如果是,那么这种影响是正面的还是负面的。
4

1 回答 1

9

直接使用类可能会更快,不会更慢。如果 JVM 看到一个具体的类,它就知道“调用谁”。不一定完全因为可能有子类,除非该类是最终的。JVM 甚至可能还没有看到稍后加载的子类。

  • 对于最终类,方法调用可以优化为本地 CALL 指令。那是小事一桩。

  • 如果该类不是最终的,但还没有加载子类,则在开始的某处进行一次附加检查是相同的。当检查失败时,JVM 必须丢弃这个过度乐观编译的方法并重新编译(没什么大不了的)。

  • 当有子类时,一切都取决于在给定的调用站点上实际遇到了多少子类。如果只有一个,那么快速检查就足以验证给定的类是预期的类(通过将这个测试移出循环等,这个开销变得可以忽略不计)。

  • 具有更多候选者的情况显然更慢(Google for bimorphic and megamorphic)。

显然,没有什么可以更快地通过接口进行调用。

如果有多个实现并且从一个调用站点调用了多个实现,那么就会产生虚拟调用调度的开销。有关更多详细信息,请参阅此答案和此基准

于 2013-11-11T10:01:04.037 回答