为什么任何标记为final的类都不允许编译器对方法调用进行虚拟化

时间:2015-06-02 18:50:48

标签: java compiler-construction

this article中,我很惊讶地读到:

  

我总是想象有一个final方法意味着编译器会使用invokespecial而不是invokevirtual编译对它的所有调用,以“devirtualize”方法调用,因为它已经知道确保在编译时转移执行的位置。在编译时这样做似乎是一个微不足道的优化,而将这一点留给JIT要复杂得多。但不,编译器不会这样做。这样做甚至都不合法!

在编译时执行此操作似乎是一个简单的优化,因为它已经确定在编译时确定传输执行的位置。这不会发生的原因是什么?

1 个答案:

答案 0 :(得分:3)

发布the answer that EJP pointed out in the comments

  

Java有一个单独的编译模型,因此它禁止跨文件优化(有一个值得注意的例外,编译时常量内联)。如果将方法更改为非final,并且不重新编译客户端,该怎么办?如果你进行运行时字节码替换(搜索" instrumentation")?

,该怎么办?      

旁注:作为工程师,您的期望应该是该工具的功能。这不是C ++。在你能负担得起翻译的地方,字节码优化是不成熟的优化。

     

让你的思想面向对象。你要求编译器这样做,让它决定幕后最好的;如果20yo编译器不这样做,它可能不重要。 -O有很好的文档记录(至少在Oracle的JDK上),它只是内联声明它们的文件中的私有和静态方法。