我已经读过,制作最终的东西,然后在循环中使用它会带来更好的性能,但它对一切都有好处吗?我有很多地方没有循环,但我将final添加到局部变量。是让它变慢还是仍然好?
还有一些地方我有一个全局变量final(例如android paint),这是否意味着我在循环中使用它时不必将它作为局部最终版本?
答案 0 :(得分:7)
你应该考虑的第一件事是;我可以编写此代码的最简单,最清晰的方法是什么。这通常表现良好。
final
局部变量不太可能影响性能。当你有很长的方法时,它们可以帮助澄清,但我建议分解方法是一种更好的方法。
final
字段可以在很小程度上影响性能,但更好的理由是final
是明确表示此字段永远不会更改(这也有助于JIT)
答案 1 :(得分:4)
不要考虑性能。对象成员(字段)上的final
具有可以提高性能的重要内存语义(但更重要的是,它通常需要使代码正常工作)。你应该随时将final
放在对象成员身上。但是对于局部变量,只有在它可以提高代码可重复性的情况下才能使用它,或者可以在维护者触摸代码时防止错误。
Java社区的普遍共识是,final
对每个局部变量都会使代码难以阅读。在性能方面,您可以预期不会进行优化,因为编译器很容易分析局部变量。换句话说,编译器可以自己解决它。
答案 2 :(得分:3)
根据我的经验,大多数变量都可以声明为final
。
然而,它看起来非常难看。这是我反对它的主要观点。
如果程序的一部分不是性能关键,请注意过早优化。
答案 3 :(得分:2)
这是我的2美分:
使用final on属性来最小化可变性并出于文档目的,如果在内部/匿名类中使用它们,则只对局部变量使用final。
不要将其用于微观优化!特别是不要在类或方法上使用它们,因为您认为它会提高性能。使类和方法最终为禁止继承或覆盖方法。
答案 4 :(得分:2)
在可能的情况下(对于字段和变量,而不是类和方法),使用final是一种很好的形式,如果没有其他原因,它会使测试变得更容易。决赛永远不会对表现产生负面影响。
答案 5 :(得分:1)
最终的属性不应对性能产生任何影响。除了:在多线程环境中,多个线程访问同一个字段,如果必须重新加载,则“不知道”。局部变量的最终结果根本没有影响,因为除了本地范围之外的任何东西都无法访问它们。 最终的方法可以在JIT编译期间产生影响。如果一个方法是final和small,那么编译器可以在循环中内联它,因为很明显没有人会覆盖它。 我通常根本不使用final属性,因为最终属性不能轻易地从DB加载等。声明参数方法最终lokos丑陋(我从来没有在我的代码中分配它们)但可能会阻止来自错字的简单错误。但是,如果你开始为你的变量使用专有名称,你就会发错误。
答案 6 :(得分:0)
理论上,如果你制作一个局部变量final,它可以进行优化。我不认为让它们最终自己确实提高了性能,因为优化器可能已经检测到当地人不会改变。也就是说,帮助它不会有什么坏处。
在某些情况下,将一个变量更改为两个变量会有所帮助,例如:从这个
String a = "foo";
if (lol) a += "bar";
for(.. 1000 ...) doSomething(a);
到
final String a;
{
String ma = "foo";
if (lol) ma += "bar";
a = ma;
}
for(.. 1000 ...) doSomething(a);
免责声明:我不是JIT专家。
答案 7 :(得分:0)
最终变量是常量,因此编译器可以生成常量值而不是变量引用指令。当然,这会提高速度(通常也会提高尺寸)。
还有一些地方我有一个全局变量final(例如android paint),这是否意味着我在循环中使用它时不必将它作为局部最终版本?
对不起,您的意思是说您不必:
final int somefinalvalue = 0;
void amethod() {
final int somefinalvalue = 0; // repeated from global one
}
还是什么?请记住,如果您声明与全局变量具有相同名称的局部变量,则会“影响”全局变量。即它实际上是一个完全不同的变量。如果您已经拥有全局的,那就使用它。无需重新申报。
答案 8 :(得分:0)
正如@ perter-lawrey所提到的,我认为这不应该是你的第一个问题。首先,编译器优化可以做很多事情;第二,有一些工具可以分析生成的类文件并执行相同的操作,例如ProGuard: java shrinker, optimizer, obfuscator, and preverifier.