为什么在Java中将局部variables和方法参数标记为“final”?

在Java中,您可以使用final关键字限定本地variables和方法参数。

public static void foo(final int x) { final String qwerty = "bar"; } 

这样做会导致无法在方法的主体中重新分配x和qwerty。

这种做法会使您的代码朝着不可变性的方向发展,而这一般被认为是一个加号。 但是,它也倾向于将代码与“最终”出现在各处。 你对Java中的局部variables和方法参数的最终关键字有什么看法?

只要适当,你应该尽量做到这一点。 除了在“意外”尝试修改某个值时发出警告,它还会向编译器提供信息,以便更好地优化类文件。 这是Robert Simmons,Jr.编写的“Hardcore Java”一书中的重点之一。实际上,本书的第二章全部都是关于使用final来促进优化和防止逻辑错误。 诸如PMD之类的静态分析工具和Eclipse的内置SA标记出这种情况。

我个人的意见是,这是浪费时间。 我相信视觉上的混乱和冗长是不值得的。

我从来没有遇到过重新分配的情况(记住,这不会使对象不可变,所有这些都意味着你不能重新分配一个variables的引用)。

但是,当然,这全是个人喜好;-)

最终确定参数可以保证方法中任何位置使用的值是指传递的值。 否则,你必须精神分析给定位置上方的所有代码,以知道该参数在这一点上的值。

因此, 使用最终使你的代码更不易读,维护,所有本身:)

最后的局部variables取决于意图,在我看来不那么重要。 取决于发生的事情。

在局部variables的情况下,我倾向于避免这种情况。 它会导致视觉混乱,通常是不必要的 – 一个function应该足够短或集中在一个单一的影响,让你很快看到,你正在修改一些不应该的东西。

在幻数的情况下,我会把它们作为一个不变的私人领域,而不是在代码中。

我只在必要的情况下使用final(例如,将值传递给匿名类)。

由于Java的“ 通过引用 ”行为(偶尔)混淆的性质,我绝对同意完成参数var的。

完成本地var的似乎有点矫枉过正国际海事组织。

做吧。

这是关于可读性。 当你知道variables只被赋值一次而且只赋值一次时,可以更容易地推断程序的可能状态。

一个体面的替代方法是当一个参数被赋值时,或者一个variables(除了循环variables之外)被多次赋值时,打开IDE警告。

决赛有三个很好的理由:

  • 由构造函数设置的实例variables只能是不可变的
  • 不要被重写的方法变成最终的,而是用真实的原因来使用它,而不是默认的
  • 局部variables或参数要在方法内的不一致类中使用,必须是最终的

像方法一样,局部variables和参数不需要声明为final。 正如其他人之前所说的,这会使代码变得越来越不可读,编译器性能优化的代码变得很less,这对于大多数代码片段来说并不是真正的原因。

尽pipe它造成了一点点混乱,但是final还是值得的。 Ides例如eclipse可以自动把final如果你configuration它这样做。

如果你想把这些parameter passing给匿名类,那么使局部variables和方法参数成为final是很重要的,就像你实例化一个匿名Thread并想访问run()方法体内的那些参数一样。

除此之外,我不确定通过编译器优化可以获得更好的性能。 是否要优化它,取决于具体的编译器实现…

这将是很好的知道使用final的任何performance统计…

你为什么要? 您编写了这个方法,所以任何修改它的人都可以从qwerty中删除最后一个关键字并重新分配它。 至于方法签名,相同的推理,虽然我不知道它会做什么,你的类的子类…他们可能会inheritance最后的参数,即使他们重写的方法,无法去确定x。 尝试一下,看看它是否可行。

唯一真正的好处就是如果你使这个参数不变,并且它传递给了孩子们。 否则,你只是混乱你的代码没有特别好的理由。 如果它不会强迫任何人遵守你的规则,那么你最好留下一个好的评论,为什么你不应该改变这个参数或variables,而不是给出最终的修饰符。

编辑

在回应评论时,我会补充说,如果你看到性能问题,使你的本地variables和参数最终可以让编译器更好地优化你的代码。 但是,从您的代码不可变性的angular度来看,我坚持原来的声明。

我让Eclipse在匿名类中使用它,因为我使用了Google Collection API。

如果我们认为它们不会被重新分配或者不应该被重新分配,我们在这里为局部variables做这个。

参数不是最终的,因为我们有一个检查重新分配参数的Checkstyle-Check。 当然,没有人会想要重新分配参数variables。