8

下面的代码片段(摘自真实世界的代码)在 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 脚本只是拒绝通过。
4

1 回答 1

4

这看起来像一个错误,正如 Oracle 的错误数据库在这里报告的那样。

根据JLS §7.5, - 语句的顺序import应该无关紧要。

于 2013-07-12T00:39:09.460 回答