这是在声明像这样的对象时使用接口/基类引用的一般编码实践:
InterfaceIF ref = new SomeObject();
Run Code Online (Sandbox Code Playgroud)
我知道这提供了松散耦合,我们可以使用新的实现来更改/编写新类,而不会影响很多代码.
但有一点我无法理解,而且没有回答的问题是:
直接使用该类可能更快,从不慢.如果JVM看到一个具体的类,它就会知道"谁来调用".不一定完全可能有子类,除非该类是最终的.可能有一些JVM尚未看到的子类,后来加载.
对于最终类,可以将方法调用优化为本机CALL指令.这是一个微不足道的案例.
如果类不是最终的,但是还没有加载子类,那么在开头的某个地方只需要一个额外的检查.当检查失败时,JVM必须抛弃这种过度乐观的编译方法并重新编译(没什么大不了的).
当有子类时,一切都取决于在给定的调用站点上实际遇到多少子类.如果只有一个,那么快速检查就足以验证给定的类是否是预期的类(通过将此测试移出循环等,这个开销变得可以忽略不计).
有更多候选人的案件显然较慢(Google为双形和巨型).
显然,没有什么可以通过接口更快地进行呼叫.
如果有多个实现,并且从呼叫站点调用了多个实现,则会产生虚拟呼叫调度的开销.有关详细信息,请参阅此答案和此基准.
| 归档时间: |
|
| 查看次数: |
1130 次 |
| 最近记录: |