在this article中,我很惊讶地读到:
我总是想象有一个
final
方法意味着编译器会使用invokespecial
而不是invokevirtual
编译对它的所有调用,以“devirtualize”方法调用,因为它已经知道确保在编译时转移执行的位置。在编译时这样做似乎是一个微不足道的优化,而将这一点留给JIT要复杂得多。但不,编译器不会这样做。这样做甚至都不合法!
在编译时执行此操作似乎是一个简单的优化,因为它已经确定在编译时确定传输执行的位置。这不会发生的原因是什么?
答案 0 :(得分:3)
发布the answer that EJP pointed out in the comments:
Java有一个单独的编译模型,因此它禁止跨文件优化(有一个值得注意的例外,编译时常量内联)。如果将方法更改为非final,并且不重新编译客户端,该怎么办?如果你进行运行时字节码替换(搜索" instrumentation")?
,该怎么办?旁注:作为工程师,您的期望应该是该工具的功能。这不是C ++。在你能负担得起翻译的地方,字节码优化是不成熟的优化。
让你的思想面向对象。你要求编译器这样做,让它决定幕后最好的;如果20yo编译器不这样做,它可能不重要。 -O有很好的文档记录(至少在Oracle的JDK上),它只是内联声明它们的文件中的私有和静态方法。