总是使用最终?

我已经读过,制作最终的东西,然后在循环中使用它会带来更好的性能,但它对一切都有好处吗? 我有很多地方没有循环,但我将final添加到局部变量。 它会使它变慢还是仍然好?

还有一些地方我有一个全局变量final(例如android paint),这是否意味着我在循环中使用它时不必将它作为局部最终版本?

你应该考虑的第一件事是; 我可以编写此代码的最简单,最清晰的方法是什么。 这通常表现良好。

final局部变量不太可能影响性能。 当你有很长的方法时,它们可以帮助澄清,但我建议分解方法是一种更好的方法。

final字段可以在很小程度上影响性能,但是使其成为final字段的更好理由是要明确该字段永远不会更改(这也有助于JIT)

不要考虑性能。 对象成员(字段)上的final具有显着的内存语义,可以提高性能(但更重要的是,它通常需要使代码正常工作)。 你应该随时把对象放在final对象上。 但是,对于局部变量, 只有在它可以提高代码重新连接性时才能使用它,或者可以在维护者触摸代码时防止出现错误

Java社区的普遍共识是,每个局部变量的final都会使代码难以阅读。 在性能方面,您可以预期没有优化,因为编译器很容易分析局部变量。 换句话说,编译器可以自己解决它。

根据我的经验,大多数变量都可以声明为final

但是,它看起来非常难看。 这是我反对它的主要观点。

如果程序的一部分不是性能关键,请注意过早优化。

如果没有其它原因使得测试更容易,那么在可能的情况下(对于字段和变量,而不是类和方法)使用final是一种很好的forms。 决赛永远不会对表现产生负面影响。

这是我的2美分:

使用final on属性来最小化可变性并出于文档目的,如果在内部/匿名类中使用它们,则仅对局部变量使用final。

不要用它来进行微观优化! 特别是不要在类或方法上使用它们,因为您认为它会提高性能。 使类和方法最终禁止inheritance或覆盖方法。

关于属性的最终结果不应对性能产生任何影响。 除了:在multithreading环境中,多个线程访问同一个字段并且“不知道”是否必须重新加载它。 关于局部变量的最终结果根本没有影响,因为除了本地范围之外的任何东西都无法访问它们。 最终的方法可以在JIT编译期间产生影响。 如果一个方法是final和small,那么编译器可以在循环中内联它,因为很明显没有人会覆盖它。 我通常根本不使用final属性,因为最终属性不能轻易地从DB加载等。声明参数方法最终lokos丑陋(我从来没有在我的代码中分配它们)但可能会阻止来自错字的简单错误。 但是,如果你开始为你的变量使用专有名称,你就不会发错。

理论上,如果你创建一个局部变量fi​​nal,它可以进行优化。 我不认为让它们最终自己确实提高了性能,因为优化器可能已经检测到当地人不会改变。 也就是说,帮助它有点伤害。

在某些情况下,将有助于将一个变量更改为两个,例如从中

 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(例如android paint),这是否意味着我在循环中使用它时不必将它作为局部最终版本?

对不起,您的意思是说您没有:

 final int somefinalvalue = 0; void amethod() { final int somefinalvalue = 0; // repeated from global one } 

或者是什么? 请记住,如果声明与全局变量具有相同名称的局部变量,则会“影响”全局变量。 即它实际上是一个完全不同的变量。 如果你已经拥有全球的那个,那就用吧。 无需重新申报。

我不认为这应该是你关注的第一个问题,正如@ perter-lawrey所提到的那样。 首先,编译器优化可以做很多事情; 第二,有一些工具可以分析生成的类文件并执行相同的操作,例如, ProGuard:java shrinker,optimizer,obfuscator和preverifier。