次のスニペット (実際のコードから抜粋) は、コンパイルして 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 スクリプトは処理を拒否しました。