在Java中声明方法参数final是否有任何性能原因?

在Java中声明方法参数final是否有任何性能原因?,java,performance,final,Java,Performance,Final,在Java中声明方法参数final是否有任何性能原因 例如: public void foo(int bar) { ... } 与: public void foo(final int bar) { ... } 假设类加载后运行的编译器(如JIT编译器)只能在foo()中读取bar,而从不修改。因此,声明为final的方法可能有一些性能优势 哦,还有一个很好的资源 最后一个参数的唯一好处是可以在匿名嵌套类中使用它。如果参数从未更改,编译器将在正常操作中检测到该参数,即使没有最后的修饰符。很

在Java中声明方法参数final是否有任何性能原因

例如:

public void foo(int bar) { ... }
与:

public void foo(final int bar) { ... }

假设类加载后运行的编译器(如JIT编译器)只能在
foo()

中读取
bar
,而从不修改
。因此,声明为final的方法可能有一些性能优势

哦,还有一个很好的资源


最后一个参数的唯一好处是可以在匿名嵌套类中使用它。如果参数从未更改,编译器将在正常操作中检测到该参数,即使没有最后的修饰符。很少有错误是由意外分配的参数引起的-如果您的方法足够大,需要这种级别的工程,请将其缩小-您调用的方法无法更改您的参数。

局部变量和参数的类文件中不会出现final关键字,因此,它不会影响运行时性能。唯一的用途是澄清编码器的意图,即变量不被改变(许多人认为使用它的可疑原因),以及处理匿名内部类。
对于方法本身的最终修饰符是否具有任何性能增益,有很多争论,因为不管修饰符是什么,优化编译器都会在运行时内联这些方法。在这种情况下,它也应该只用于限制方法的覆盖。

< P>我假设编译器可能删除所有具有基元类型的私有静态最终变量,例如int,并直接在代码中直接与C++一样。
然而,我不知道这是否是在实践中做的,但它可以这样做,以节省一些内存

还有一点,使用方法中声明的非最终局部变量,内部类实例可能会超过堆栈框架,因此当内部对象仍然存在时,局部变量可能会消失

问题是参数被声明为最终变量,这对性能没有影响。关于现代JIT(热点)final根本没有任何(可测量的)性能影响,无论是应用于参数还是类。您链接的两篇文章都表明final对于开发人员来说是一个语义标记,JIT编译器可以使用final(但正如其他人指出的,他们并不真正需要这些信息)。所以final是相当语义的,这与现代C/++编译器并行,它能够推断变量和方法的常量,即使它们没有显式标记为const。您可能会认为final变量/参数可以作为循环变量进行优化…但是一个好的编译器/运行时应该能够在没有final的情况下解决这一问题…我已经看到Sun的编译器发出了当两种方法之间的唯一区别是局部变量的“终结性”时,字节码稍微短一些。微优化是一件真实的事情,编译器确实在进行微优化。当然,真正重要的是JIT如何处理字节码,当编译成字节码时,本地引用失去了“最终性”。我认为这就是为什么有那么多关于最终局部变量的猜测:结果是什么是非常不确定的。然而,使用最终局部变量会影响字节码的价值,因为它是不确定的,所以也没有任何方法依赖于优化。当然,自2008年给出最初答案以来,虚拟机实现可能发生了很大变化;-)“很少有错误是由意外分配的参数引起的”。这比你想象的更普遍…@RAY你可能是对的,实际上我没有任何数据(超出我自己的经验)来支持这一说法。@DobesVandermeer更准确地说,这并不是“最终参数的好处”。您所描述的只是使匿名嵌套类的局部范围可见的任何局部变量(其中我包括参数as)所需的语法。问题不在于私有statc final变量。我想不出编译器会关心您是否声明了方法参数final的原因。但这个问题的真正答案是——写两个函数,一个带最终参数,一个带常规参数。每次运行一百万次,看看是否有任何明显的运行时差异。如果您担心性能问题,那么对代码进行一些分析工作,并找出到底是什么让您速度变慢是非常重要的。这几乎肯定不是您所期望的:)我建议您永远不要编写微基准测试。你不知道JIT可以做什么优化,什么时候做,你可能会对它的行为产生错误的想法,仅仅是做一个“简单的测试用例”,这可能是,但是这里没有人写过或建议过微基准测试…@Mike Blandford的回答建议使用微基准测试,不是吗?用Java编写微基准测试是一件非常棘手的事情