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

时间:2012-01-29 08:24:33

标签: 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    }

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

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

3 个答案:

答案 0 :(得分:13)

这可能是您正在使用的Java编译器中的错误。根据{{​​3}},增强型for语句中变量的范围是包含的语句。 (这似乎排除了:右侧的可迭代或数组表达式。)

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

修改 只是为了踢,我将此作为错误报告提交给Sun.我们将看看Java工程师是否认为它是JLS或javac中的错误(或者如果他们有其他解释)。错误ID为Java Language Specification (section 14.14.2),但几天内不会发布到外部数据库。

答案 1 :(得分:7)

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

for (Integer line : this.line.getElements()) {
}

答案 2 :(得分:-2)

使用IntelliJ时,它会自动解析所有文件。但是对于javac,它可能无法编译所有程序,特别是如果它们之前已编译过。

假设你有B类(没有getElements())并且你编译它。稍后你添加方法并且只编译A,它会抱怨B没有那个方法,因为上次你编译它时,没有这样的方法。

解决这个问题的方法是在编译或使用像maven这样的构建工具之前删除所有* .class文件。