在没有初始化程序的情况下将局部变量声明为final,并在if语句中指定

时间:2012-01-18 14:31:47

标签: java eclipse variables declaration final

我只是做了一个小代码更改来沉默FindBugs警告,该警告需要将一些代码移动到匿名内部类。为了访问某些变量,我必须将它们声明为final。所以这是更改后的代码段:

final File[] libPath; // libPath is final but assignment takes place later
if (libraryPath != null) {
    libPath = pathToFiles(libraryPath);
} else {
    libPath = new File[0];
}

在当前的Eclipse(版本3.7.1)中,使用设置为Java 6的语言编译得很好。但是我很确定这曾经在某些先前版本中出错。似乎编译器在确定存在时接受此构造。

我的问题是:这在Java 6中是否合法,或者由于Java 7支持的副作用被添加到eclipse 3.7.1中,它现在是否可行?我们已经看到了在3.7.1中使用泛型的某些用法的副作用,但是没有在3.7.0中编译。

6 个答案:

答案 0 :(得分:14)

这没关系。它被称为空白最终

引自wiki:

  

最终变量只能通过一次初始化一次   初始化程序或赋值语句。它不需要初始化   声明点:这被称为"空白决赛"变量。一个   必须明确赋值类的空白最终实例变量   在声明它的类的每个构造函数的末尾;   同样,必须明确指定空白的最终静态变量   在声明它的类的静态初始值设定项中:   否则,在两种情况下都会发生编译时错误。 [4](注:如果   变量是一个引用,这意味着变量不能   重新绑定引用另一个对象。但它的对象   如果引用最初是可变的,那么引用仍然是可变的。)

     

空白最终

     

在Java 1.1中引入的空白final是一个最终变量   其声明缺少初始化程序。 [5] [6]空白决赛只能   分配一次,并且在分配发生时必须取消分配。在   为了做到这一点,Java编译器运行流分析以确保,   对于空白最终变量的每个赋值,变量是   在任务之前绝对未分配;否则编译时   发生错误。[7]

     

通常,Java编译器将确保空白final不是   使用,直到它被分配一个值,并且一旦分配了值,   现在最终变量不能重新分配另一个值。[8]

link:http://en.wikipedia.org/wiki/Final_%28Java%29

答案 1 :(得分:8)

自Java 1.1以来,这是允许并且工作正常,并且不会让您遇到其他编译器或IDE的麻烦。

它是Java中的标准行为,并且首先在Java Language Specification 2nd Edition中正式指定。

答案 2 :(得分:1)

Java语言规范包含专门针对此行为的整章(Chapter 16 Definite Assignment)。

这种行为是彻底定义的,所以当你说在以前的版本中曾经产生错误时,我认为你误解了一些东西。

答案 3 :(得分:0)

没关系。变量没有值,只分配一次。如果你最初给它一个null值,它将会失败。

答案 4 :(得分:0)

我强烈建议改用此代码:

final File[] libPath = ibraryPath == null ? new File[0] : pathToFiles(libraryPath);

这不依赖于任何编译器版本,但是100%支持具有明确含义的Java。

答案 5 :(得分:0)

是的,这将起作用,并且在我见过的所有java版本中都可以安全使用(1.3 +)。

final 意味着一旦初始化对象就无法更改对象的值,如果在声明它已经破坏时放置了null。