Java 为什么任何标有“最终”的班级都会获胜';不允许编译器对方法调用进行设备化

Java 为什么任何标有“最终”的班级都会获胜';不允许编译器对方法调用进行设备化,java,compiler-construction,Java,Compiler Construction,在这本书中,我惊讶地读到: 我一直认为拥有一个final方法意味着编译器将使用invokespecial而不是invokevirtual来编译对它的所有调用,以“设备化”方法调用,因为它在编译时已经确定在哪里传输执行。在编译时执行此操作似乎是一个微不足道的优化,而让JIT来完成则要复杂得多。但是不,编译器不这样做。这样做甚至都不合法 在编译时这样做似乎是一个微不足道的优化,因为它在编译时已经确定了将执行转移到何处。这种情况没有发生的原因是什么?发布: Java有一个单独的编译模型,因此它禁止跨文

在这本书中,我惊讶地读到:

我一直认为拥有一个
final
方法意味着编译器将使用
invokespecial
而不是
invokevirtual
来编译对它的所有调用,以“设备化”方法调用,因为它在编译时已经确定在哪里传输执行。在编译时执行此操作似乎是一个微不足道的优化,而让JIT来完成则要复杂得多。但是不,编译器不这样做。这样做甚至都不合法

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

发布:

Java有一个单独的编译模型,因此它禁止跨文件优化(编译时常量内联除外)。如果将方法更改为非final,并且不重新编译客户机,该怎么办?如果您执行运行时字节码替换(搜索“指令插入”)会怎么样

旁注:作为一名工程师,您的期望应该是该工具的功能。这不是C++。如果你买得起解释器,字节码优化就是过早的优化

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


请澄清您的具体问题或添加其他详细信息,以突出显示您所需的内容。正如目前编写的那样,很难准确说出您的要求。
invokestatic
用于静态方法。最后的方法不一定是静态的。谢谢你指出这一点。但是为什么invokevirtual编译器应该优化它,因为它可以确保方法是继承的?
invokeSpecial
完全是另外一回事。我认为这不是一个内容丰富的博客。2012年12月19日“匿名”的评论似乎回答了这个问题。不要对非代码文本使用代码格式。