在Java中,您可以使用final关键字限定局部变量和方法参数。
public static void foo(final int x) {
final String qwerty = "bar";
}
这样做会导致无法在方法体中重新分配x和qwerty。
这种做法使你的代码朝着不变性的方向推动,这通常被认为是一个加分。但是,它也会使代码混乱,“最终”出现在各处。您对Java中的局部变量和方法参数的final关键字有什么看法?
答案 0 :(得分:53)
只要合适,你应该尝试这样做。除了在“意外”尝试修改值时发出警告,它还为编译器提供了可以更好地优化类文件的信息。这是Robert Simmons,Jr。的书中的“Hardcore Java”中的一点。实际上,本书花了所有第二章关于final的使用来促进优化和防止逻辑错误。出于这个原因,静态分析工具(如PMD和Eclipse的内置SA)标记了这些类型的案例。
答案 1 :(得分:27)
我个人认为这是浪费时间。我相信视觉上的混乱和额外的冗长是不值得的。
我从来没有遇到过我已经重新分配的情况(记住,这不会使对象成为不可变的,这意味着你无法重新分配对变量的另一个引用)错误的变量。
但是,当然,这都是个人偏好; - )
答案 2 :(得分:8)
使参数最终保证方法中任何位置使用的值都是指传递的值。否则,您必须在心理上解析给定位置上方的所有代码,以了解该参数在该点的值。
因此,不使用final会使您的代码本身不易读取和维护:)
最终的局部变量取决于意图,在我看来并不重要。取决于发生了什么。
答案 3 :(得分:6)
在局部变量的情况下,我倾向于避免这种情况。它会造成视觉混乱,通常是不必要的 - 一个功能应该足够短或专注于一次冲击,让你快速看到你修改了一些不应该的东西。
对于幻数,我会将它们作为一个常量私有字段而不是代码。
我只在有必要的情况下使用final(例如,将值传递给匿名类)。
答案 4 :(得分:5)
由于Java的“pass by reference”行为(偶尔)令人困惑,我绝对同意最终确定参数var。
最终确定局部变量似乎有点过分了IMO。
答案 5 :(得分:3)
是的。
这是关于可读性的。当您知道变量被分配一次且仅被分配一次时,更容易推断出程序的可能状态。
一个不错的选择是在分配参数时,或者在多次分配变量(循环变量除外)时打开IDE警告。
答案 6 :(得分:2)
最终有三个很好的理由:
与方法类似,不需要将局部变量和参数声明为final。正如其他人之前所说的那样,这会使代码变得越来越难以用于编译器性能优化的efford,这对大多数代码片段来说都不是真正的原因。
答案 7 :(得分:2)
虽然它会造成一些混乱,但值得final
。 Ides例如eclipse可以自动放置final
,如果你配置它。
答案 8 :(得分:2)
如果要将这些参数传递给匿名类,那么创建局部变量和方法参数final
是必不可少的 - 就像实例化一个匿名线程并想要访问run()方法体中的那些参数一样。 / p>
除此之外,我不确定通过编译器优化提高性能的性能优势。具体的编译器实现是否要完全优化它...
使用final
...
答案 9 :(得分:0)
你为什么要这样?您编写了该方法,因此修改它的任何人都可以始终从qwerty中删除最终关键字并重新分配。至于方法签名,同样的推理,虽然我不确定它会对你的类的子类做什么......他们可能会继承最后的参数,即使它们覆盖了方法,也无法去除x。试一试,看看它是否有效。
唯一真正的好处是,如果你让参数成为不可变的并且它会延续到孩子身上。否则,您只是因为没有特别好的理由而使代码混乱。如果它不会强迫任何人遵守你的规则,你最好留下一个好的评论,因为你不应该改变那个参数或变量,而不是给出最终修饰符。
修改的
在回复评论时,我将补充一点,如果您看到性能问题,那么使您的局部变量和参数最终可以让编译器更好地优化您的代码。但是,从代码不变性的角度来看,我坚持原来的陈述。
答案 10 :(得分:0)
当我在匿名类中使用时,我让Eclipse为我做这件事,由于我使用了Google Collection API,这种情况正在增加。
答案 11 :(得分:0)
如果我们认为它们不会被重新分配或不应该被重新分配,我们在这里为局部变量做。
参数不是最终的,因为我们有一个检查重新分配参数的Checkstyle-Check。当然,没有人愿意重新分配参数变量。