变量名称等于字段名称的foreach

Vla*_*nov 21 java foreach intellij-idea

编译以下代码时发现有趣的事情:

1    class A {
2        
3     private B line;
4   
5     public void foo() {
6       for (Integer line : line.getElements()) {
7    
8       }
9     }
10    }
11    
12    class B {
13    
14      List<Integer> getElements() {
15         return null; // doesn't matter
16      }
17    }
Run Code Online (Sandbox Code Playgroud)

注意第6行:我们看到变量名等于字段名.IntelliJ Idea 11忽略了这一点,并认为这里没有麻烦.但java编译器告诉我'line没有方法getElements'.那么,有两个问题:

  1. 我应该在Idea中提交错误报告吗?
  2. 为什么来自Java的错误消息是这样的?是不是能够发现错误?这里有什么机制?字段变量的遮蔽?

Ted*_*opp 13

这可能是您正在使用的Java编译器中的错误.根据Java语言规范(第14.14.2节),增强for语句中变量的范围是包含的语句.(这似乎排除了右边的iterable或数组表达式:.)

您可以使用以解决此问题this.line.getElements().

编辑 只是为了踢,我把它作为一个错误报告提交给Sun. 我们将看看Java工程师是否认为它是JLS或javac中的错误(或者如果他们有其他解释).错误ID是7139681,虽然它不会在几天内发布到外部数据库.


Hur*_*rda 7

如果使用与字段相同的名称声明局部变量(这是您所做的),则可以将字段变量作为this.name.

for (Integer line : this.line.getElements()) {
}
Run Code Online (Sandbox Code Playgroud)

  • [Java语言规范的第14.14.2节](http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.14.2)似乎建议局部变量的范围只是封闭的语句(`{}`之间的部分),并且不包括`:`右边括号内的表达式. (6认同)