javac或Hotspot会自动添加'final'作为不变变量的优化吗?

时间:2011-04-05 09:06:18

标签: java compiler-construction final jvm-hotspot

共识似乎是将成员变量标记为final有一个性能优势,因为它们永远不需要从主内存重新加载。我的问题是,当变量无法改变时,javac或Hotspot会自动为我做这件事。例如,javac将在下面的这个课程中做出'x'决赛......

public class MyClass {
   private String x;

   MyClass(String x) {
      this.x = x;
   }

   public String getX() {
      return x;
   }
}

在次要问题上,有没有人提出经验证据表明成员最终会使代码运行得更快?在进行远程调用或数据库查找的任何应用程序中,任何好处肯定都可以忽略不计?

4 个答案:

答案 0 :(得分:4)

与许多性能“增强”一样,通常更好的问一下;什么更容易理解和推理?例如如果一个领域是最终的,我知道它不会在任何地方改变。这通常会导致更优化的代码,但更重要的是它应该是更易于维护的代码。 ;)

当然,我做任何可以作为最终决赛的领域。我个人认为final是默认行为,你必须使用var之类的关键字来使其变得可变。

答案 1 :(得分:2)

允许javac这样做会是一个大错。由于可能存在可能依赖于正在编译的代码(模块化)的不同jar中的代码,因此为了优化起见,在编译时更改代码不是可行的选择。

至于第二个参数“永远不需要从主内存重新加载”,需要记住大多数实例变量都是缓存的。 最终仅表示不变性,它不保证波动性(volatile ==总是从主内存中获取最新信息)。因此在多线程环境中需要lock和volatile关键字。

至于热点的情况,我不知道,并希望听到更多关于它的信息。 最终常量可以在编译时进行内联,从而允许适度的性能提升。参考in-lining in java

上的问题

编辑:

请注意,最终表示需要采取一定程度的不变性。它不保证状态不能改变,它只指定可以修改对象引用。 final 表示原始数据类型

的不变性

答案 2 :(得分:1)

AFAIK,他们没有,因此,你受到轻微的惩罚。但是,这可以使用Eclipse“Cleanup”等IDE工具自动完成。

答案 3 :(得分:0)

我相信现代JVM(Hotspot编译器)确实检测到值没有改变,因此在制作参数变量 {{时没有性能优势1}}你自己。 (如果这是错误的,请提供链接或测试用例。)有一个例外:常量(final)。

但是,最终的方法可能会有所不同。在这种情况下,它可以提高性能(我不完全确定在什么情况下)。顺便说一句,提高性能的一点是使函数静态(如果可能的话)。

我对static final的问题是它使代码混乱。如果final是默认值,那就太好了。