如果使用,字节码的效率不会显著提高或降低,因为 Java 字节码编译器在优化方面通常很少。效率加成(如果有)将在 JIT 编译器1 生成的本机代码中。final
从理论上讲,使用 为 JIT 编译器提供了一个提示,应该可以帮助它进行优化。在实践中,最近的HotSpot JIT编译器可以通过忽略您的提示来做得更好。例如,现代 JIT 编译器通常执行全局分析,以确定给定的方法调用是否是对应用程序当前加载的类上下文中的叶方法的调用。此分析比您的提示更准确,运行时甚至可以检测何时加载了使分析无效的新类...并重做受影响代码的分析和本机代码生成。final
final
使用 还有其他语义后果:final
- 将变量声明为可防止您意外更改它。(并向读者表达您的意图。
final
- 将方法声明为可防止在子类中重写。
final
- 将类声明为可完全防止子类化。
final
- 将字段声明为会阻止子类更改它。
final
- 将字段声明为对线程安全具有重要影响;请参阅 JLS 17.5。
final
在适当的情况下,这些都可以是好的。但是,很明显,它们通过创建子类来限制重用的选项。在决定是否使用 时,需要考虑这一点。final
因此,好的做法是(从广义上讲)表达您的设计意图,并实现您需要的其他语义效果。如果您仅用作优化提示,则不会取得多大成就。final
final
有几个例外情况可能会导致某些平台上的性能提高。final
在某些情况下,将字段声明为会更改字节码编译器处理它的方式。我在上面举了一个例子。另一个是“常量变量”情况(JLS 4.12.4),其中字段的值将由字节码编译器在当前类和其他类中内联,这可能会影响观察到的代码行为。(例如,引用常量变量不会触发类初始化。因此,添加 可能会改变类初始化的顺序。final
static final
final
可以想象,将字段或本地参数声明为可能允许小的JIT编译器优化,否则将无法完成。但是,JIT 编译器也可以推断出任何可以声明为最终字段的有效字段。(目前尚不清楚JIT编译器是否实际执行此操作,以及这是否会影响生成的本机代码。final
但是,底线保持不变。您应该使用 来表达您的设计意图,而不是作为优化提示。final
1 - 这个答案假设我们正在谈论一个具有良好JIT或AOT编译器的最新JVM。1)最早的Sun Java实现根本没有JIT编译器。2)早期的Android Java实现有编译器,这些编译器在优化方面做得很差。事实上,早期的Android开发人员文档建议进行各种源代码级微优化来弥补。此建议已被删除。