3 回答
TA贡献1775条经验 获得超11个赞
通常不是。对于虚方法,HotSpot会跟踪方法是否实际被覆盖,并且能够在假设方法尚未被覆盖的情况下执行优化,例如内联- 直到它加载一个覆盖方法的类,此时它可以撤消(或部分撤消)这些优化。
(当然,这假设您正在使用HotSpot - 但它是迄今为止最常见的JVM,所以...)
在我看来,你应该final
基于清晰的设计和可读性而不是出于性能原因。如果您出于性能原因想要更改任何内容,则应在将最清晰的代码变形之前执行适当的测量 - 这样您就可以决定是否所获得的额外性能值得更差的可读性/设计。(根据我的经验,它几乎不值得; YMMV。)
编辑:由于已经提到了最后的领域,所以值得提出的是,无论如何,在清晰的设计方面,它们通常都是个好主意。它们还在跨线程可见性方面改变了保证行为:在构造函数完成之后,任何最终字段都保证在其他线程中立即可见。这可能是final
我经验中最常见的用法,虽然作为Josh Bloch的“继承设计或禁止它的设计”的支持者,我应该final
更频繁地使用课程......
TA贡献1942条经验 获得超3个赞
在谈论最终的局部变量时请记住,使用关键字final
将有助于编译器静态优化代码,这最终可能导致更快的代码。例如,a + b
下面示例中的最终字符串是静态连接的(在编译时)。
public class FinalTest { public static final int N_ITERATIONS = 1000000; public static String testFinal() { final String a = "a"; final String b = "b"; return a + b; } public static String testNonFinal() { String a = "a"; String b = "b"; return a + b; } public static void main(String[] args) { long tStart, tElapsed; tStart = System.currentTimeMillis(); for (int i = 0; i < N_ITERATIONS; i++) testFinal(); tElapsed = System.currentTimeMillis() - tStart; System.out.println("Method with finals took " + tElapsed + " ms"); tStart = System.currentTimeMillis(); for (int i = 0; i < N_ITERATIONS; i++) testNonFinal(); tElapsed = System.currentTimeMillis() - tStart; System.out.println("Method without finals took " + tElapsed + " ms"); }}
结果?
Method with finals took 5 msMethod without finals took 273 ms
在Java Hotspot VM 1.7.0_45-b18上测试。
那么实际的性能提升了多少?我不敢说。在大多数情况下可能是边缘的(在这个综合测试中大约270纳秒,因为完全避免了字符串连接 - 这是一种罕见的情况),但在高度优化的实用程序代码中,它可能是一个因素。在任何情况下,原始问题的答案都是肯定的,它可能会提高性能,但最多只是略微提高。
除了编译时的好处,我找不到任何证据表明关键字的使用final
对性能有任何可衡量的影响。
添加回答
举报