8

次のスニペット (実際のコードから抜粋) は、コンパイルして Eclipse で実行します。

package1/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();
        }
    }

}

package2/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 ステートメントの順序を入れ替えると:

import package2.Bar;
import package1.Outer.Mid.Inner;

...その後、Eclipse と javac の両方でコンパイルされます。明らかに、インポートステートメントの順序は重要なようです...しかし、なぜですか?

ノート:

  • これは、Java JDK 1.6.0_30 と Java JDK 1.7.0_21 を使用してテストしました。これが修正されたバグである場合は、それを知っておくとよいでしょう。
  • インターフェイスが Outer.java 内にネストされていることを考えると、package1.Outer.Mid.Innerインポートが必要でさえあるのは奇妙に思えますが、Eclipse と javac の両方でそれが必要なようです。Inner
  • 私は、同様の構造を持つ製品コードの Ant ビルドを実行しようとして、この問題を発見しました。Eclipse ではすべてが正常にビルドされていましたが、Ant スクリプトは処理を拒否しました。
4

1 に答える 1