在声明对象时,使用接口/基类引用是一种通用的编程实践,例如:
InterfaceIF ref = new SomeObject();
我了解这提供了松耦合,我们可以改变/编写新的类和新的实现而不会对大量代码产生影响。
这里也很好地解释了这一点。
但有一件事情我正在尝试理解,且在该问题中未得到回答:
- 使用接口/基类引用会影响性能吗?
- 如果会,这会带来积极的还是消极的影响?
在声明对象时,使用接口/基类引用是一种通用的编程实践,例如:
InterfaceIF ref = new SomeObject();
我了解这提供了松耦合,我们可以改变/编写新的类和新的实现而不会对大量代码产生影响。
这里也很好地解释了这一点。
但有一件事情我正在尝试理解,且在该问题中未得到回答:
直接使用类可能更快,但不会更慢。如果JVM看到一个具体的类,它就知道“该调用谁”。除非这个类是 final 的,否则可能并不完全准确,因为可能会有子类存在,甚至是之后才被JVM加载的。
对于一个 final 类,方法调用可以被优化为本地 CALL 指令。这是最简单的情况。
如果类不是 final 的,但还没有加载子类,那么只需要在开始处加上一个额外的检查即可。当检查失败时,JVM 必须丢弃这个过度优化的编译方法并重新编译(没什么大不了的)。
当存在子类时,一切都取决于在给定调用点上实际遇到了多少个子类。如果只有一个,那么快速检查就足以验证给定的类是否是预期的类(通过将此测试移出循环等方式,这个开销变得可以忽略不计)。
显然,具有更多候选者的情况会更慢(可以搜索 bimorphic 和 megamorphic)。
显然,没有任何东西能使通过接口调用变快。