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

时间:2008-11-25 04:16:23

标签: java final

在Java中,您可以使用final关键字限定局部变量和方法参数。

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

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

这种做法使你的代码朝着不变性的方向推动,这通常被认为是一个加分。但是,它也会使代码混乱,“最终”出现在各处。您对Java中的局部变量和方法参数的final关键字有什么看法?

12 个答案:

答案 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。当然,没有人愿意重新分配参数变量。