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

问题描述 投票:0回答:1

这篇文章中,我惊讶地读到:

我一直认为拥有

final
方法意味着编译器将使用
invokespecial
而不是
invokevirtual
来编译对其的所有调用,以“虚拟化”方法调用,因为它在编译时已经确定在哪里转移执行。在编译时执行此操作似乎是一个微不足道的优化,而将其留给 JIT 则要复杂得多。但不,编译器不会这样做。这样做甚至不合法!

在编译时执行此操作似乎是一个微不足道的优化,因为它在编译时已经确定将执行转移到哪里。 没有发生这种情况的原因是什么?

java
1个回答
3
投票

贴出EJP在评论中指出的答案

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

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

保持你的思维面向对象。你要求编译器去做,让它在幕后决定最好的;如果 20 岁的编译器不这样做,那么它可能并不重要。 -O 有详细记录(至少在 Oracle 的 JDK 上),它只是将私有方法和静态方法内联到声明它们的文件中。

© www.soinside.com 2019 - 2024. All rights reserved.