在编译以下代码时发现有趣的事情:
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'。所以,有两个问题:
答案 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文件。