我的问题很简单:
编译器是否将最终类中的所有方法都视为最终方法?向最终类中的方法添加final关键字是否有效?
我知道最终的方法有更好的内联机会,这就是为什么我问这个问题。
提前谢谢。
发布于 2012-01-07 09:10:02
你是对的,一个最终类中的所有方法都是隐式的final。
See here:
“请注意,您还可以声明一个完整的final类。声明为final的类不能被子类化。例如,当创建像String类这样的不可变类时,这一点特别有用。”
And here:
最终类中的所有方法都是隐式的
。
您可能也会对此感兴趣:Performance tips for the Java final keyword
发布于 2012-01-07 09:50:32
编译器是否将最终类中的所有方法都视为最终方法?
实际上,的确如此。不能重写final类中的方法。向方法添加(或删除) final关键字对此规则没有影响。
将final关键字添加到最终类中的方法会有什么效果吗?
实际上,它的影响微乎其微。它对覆盖的规则没有影响(见上),对内联也没有影响(见下文)。
可以在运行时判断一个方法是否使用final关键字声明...使用反射来查看方法的标志。所以它确实有一些效果,尽管它与99.99%的程序无关。
我知道最终方法更有可能被内联,这就是为什么我要问这个问题。
这种理解是不正确的。现代JVM中的JIT编译器跟踪应用程序加载的类中哪些方法没有被覆盖。它使用此信息和静态类型来确定特定调用是否需要虚拟类调度。如果不是,那么内联是可能的,并将根据方法体的大小使用内联。实际上,JIT编译器忽略了final的存在/缺失,并使用更精确的方法来检测允许内联方法的方法调用。
(事实上,它比这个复杂得多。应用程序可以动态加载子类,从而导致JIT编译器的方法覆盖分析变得不正确。如果发生这种情况,JVM需要使任何受影响的编译方法无效,并重新编译它们。)
底线是:
将final添加到中的方法没有性能优势在final中,将final添加到非JIT类中的方法可能是性能优势,但仅当您使用旧的Sun,或使用质量较差的final编译器的其他类似final的平台时才会如此。
如果你关心性能,最好使用一个最新的/高性能的Java平台和一个像样的即时编译器,而不是用final关键字污染你的代码库,因为这些关键字可能会在将来给你带来问题。
你在评论中写道:
@RussellZahniser我在很多地方读到了不同的东西。
互联网上充斥着陈旧的信息,其中很多都已经过时了。或者从一开始就不正确。
发布于 2012-01-07 09:10:54
可能是编译器将它们视为最终结果。
下面输出"false":
final class FinalClass {
public void testMethod() {}
}
Method method = FinalClass.class.getDeclaredMethod("testMethod");
int m = method.getModifiers();
System.out.println(Modifier.isFinal(m));https://stackoverflow.com/questions/8766476
复制相似问题