变量名称等于字段名称

2022-09-02 04:32:28

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

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编译器告诉我,“行没有方法getElements”。所以,有两个问题:

  1. 我应该在Idea中提交错误报告吗?
  2. 为什么来自Java的错误消息是这样的?它不能检测到错误吗?什么机制在这里起作用?场变量的日食?

答案 1

这可能是您正在使用的 Java 编译器中的一个错误。根据 Java 语言规范(第 14.14.2 节),增强型语句中变量的作用域是包含的语句。(这似乎排除了 右侧的可迭代或数组表达式。for:

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

编辑只是为了踢球,我把它作为错误报告提交给了Sun。我们将看看Java工程师是否认为这是JLS或javac中的错误(或者他们是否有其他解释)。bug id 是7139681,尽管它在几天内不会发布到外部数据库。


答案 2

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

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