我已经读过,做一些最终的东西,然后在循环中使用它会带来更好的性能,但它对一切都有好处吗?我有很多地方没有一个循环,但我添加最后的局部变量。它会让它变慢还是变好?总是使用Final?
还有一些地方我有一个全局变量final(例如android paint),这是否意味着我不必在循环中使用它作为本地最终?
我已经读过,做一些最终的东西,然后在循环中使用它会带来更好的性能,但它对一切都有好处吗?我有很多地方没有一个循环,但我添加最后的局部变量。它会让它变慢还是变好?总是使用Final?
还有一些地方我有一个全局变量final(例如android paint),这是否意味着我不必在循环中使用它作为本地最终?
你应该考虑的第一件事是;什么是我可以写这个代码的最简单最清晰的方式。通常这表现良好。
final
局部变量不太可能影响性能。当你有很长的方法时,它们可以帮助清晰,但我建议分手方法是一种更好的方法。
final
领域可能会影响性能,以小的程度,但一个更好的理由,使其final
是要清楚,这个领域从未改变(这也有助于JIT)
理论上讲,如果你制作一个局部变量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专家。
从我的经验,多数变量可以声明final
。
但是,它看起来非常丑陋。这是我反对的主要观点。
如果程序的部分不是性能关键,请注意过早优化。
这里是我的2美分:
使用最后的属性,以尽量减少可变性和文档的目的,只有当他们在内部/匿名类中使用的最终使用局部变量。
不要使用它进行微优化!特别是不要在类或方法中使用它们,因为您认为它会提高性能。使类和方法最终到禁止继承或重写方法。
在可能的情况下(对于字段和变量,而不是类和方法)使用final是一种很好的形式,如果没有其他原因而使测试更容易。决赛永远不会对表现产生负面影响。
最终变量是常量,因此编译器可以生成常量值而不是变量引用指令。当然,这会提高速度(并且通常也是大小)。
也有一些地方,我有一个全局变量最后(例如,android paint),这是否意味着我不必在循环中使用它作为本地最终?
对不起,你的意思是,你不必:
final int somefinalvalue = 0;
void amethod() {
final int somefinalvalue = 0; // repeated from global one
}
还是什么?请记住,如果您声明与全局名称相同的局部变量,那将会“影响”全局变量。即它实际上是一个完全不同的变量。如果你已经拥有全球性的,那么就使用它。无需重新申报。
不要考虑性能。对象成员(字段)上的final
具有显着的内存语义,可以提高性能(但更重要的是,它通常有必要使代码正常工作)。您应该始终将final
放在对象成员上。但对于局部变量,只有在维护人员接触到代码时,才能改善代码的可重用性,或者防止出现错误。
Java社区的普遍共识是,每个本地变量的final
都会使代码难以阅读。在性能方面,由于易于为编译器分析本地变量,因此可以预期不会进行优化。换句话说,编译器可以自己计算出来。
我不认为这应该是你的第一个担心,正如@ perter-lawrey所述。首先,编译器优化可以做很多事情;其次,有一些工具可以分析您生成的类文件并执行相同的操作,例如,ProGuard: java shrinker, optimizer, obfuscator, and preverifier.
属性的最终不应该对性能产生任何影响。除了:在一个多线程环境中,有多个线程访问相同的字段,“不知道”是否必须重新发布。局部变量的最终结果完全没有影响,因为除了本地范围无论如何都可以访问局部变量。在JIT编译期间,最终的方法可能会产生影响。如果一个方法是final和small,编译器可以将它内联到循环中,因为很明显没有人会覆盖它。 我通常根本不使用最终的属性,因为最终的属性不能从数据库轻松加载等等。声明参数方法最终lokos丑(我从来没有分配给他们在我的代码里面),但可能会阻止简单的错误来自typoes。但是,如果您开始使用适当的名称作为变量,则会发出此类错误。
我想补充一点,final字段与local字段的final字段非常不同。为了在并发编程中实现程序的正确性,进行字段最终决定通常是绝对必要的。 –
除了传递一个新对象到另一个线程的相当微妙的条件(我没有看到这个失败的例子),如果一个字段可能是“最终”但不是,它将表现相同。使它成为'final'清楚地表明,原语或引用不会存在线程安全问题,因为它不能被改变。注意:引用的对象仍然可以更改。 –
我只是留下规范的链接。最终变量:http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.4最终字段:http://java.sun.com/docs/books/jls/third_edition /html/memory.html#66562 tl; dr:前者对文档很有用,后者可以以明显的方式改变程序的行为。 –