下面的代码片段(摘自真实世界的代码)在 Eclipse 中编译和运行。
包1/Outer.java:
package package1;
import package1.Outer.Mid.Inner;
import package2.Bar;
public class Outer {
final Mid mid = new Mid();
public Outer() {
mid.setInner(new Inner() {
@Override public void foo() {
System.out.println("In Outer.foo()");
}
});
}
public static class Mid implements Bar {
private Inner inner;
public void setInner(Inner inner) {
this.inner = inner;
}
public Inner getInner() {
return this.inner;
}
@Override
public void bar() {}
interface Inner {
void foo();
}
}
}
包 2/Bar.java:
package package2;
public interface Bar {
void bar();
}
但是,在使用 javac 进行编译时,它会失败并出现此错误:
package1\Outer.java:31: cannot find symbol
symbol : class Bar
location: class package1.Outer
public static class Mid implements Bar {
^
package1\Outer.java:42: method does not override or implement a method from a supertype
@Override
^
2 errors
现在,如果我切换导入语句的顺序,如下所示:
import package2.Bar;
import package1.Outer.Mid.Inner;
...然后它在 Eclipse 和 javac 中编译。显然,导入语句的顺序似乎很重要……但是为什么呢?
笔记:
- 我使用 Java JDK 1.6.0_30 和 Java JDK 1.7.0_21 对此进行了测试。如果这是一个已被修复的错误,那将是很高兴知道。
package1.Outer.Mid.Inner
考虑到接口嵌套在 Outer.java 中,对我来说导入甚至是必要的,这对我来说似乎很奇怪Inner
,但 Eclipse 和 javac 似乎都需要它- 我在尝试运行具有类似结构的生产代码的 Ant 构建时发现了这个问题。在 Eclipse 中一切都很好,但 Ant 脚本只是拒绝通过。