10

次のコードがあります。

package test;

import java.util.stream.IntStream;

public class A {
    public static void main(String[] args) {
        IntStream.range(0, 10).mapToObj(n -> new Object() {
            int i = n;
        }).mapToInt(o -> o.i).forEachOrdered(System.out::println);
    }

}

このコードは、javac 1.8.0_101 でコンパイルすると正常に動作し、期待どおりに 0 から 9 の数値を生成します。

しかし、このコードを Eclipse で使用すると、次のように表示されo.iます。

i cannot be resolved or is not a field

そして、これを実行するとエラーが発生します:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    i cannot be resolved or is not a field

    at test.A.main(A.java:9)

このコードをコンパイルするために javac を使用する必要があるのはなぜですか?
そして、どうすればEclipseを動作させることができますか?

編集

私はいくつかのテストを行いましたが、ラムダでインスタンスを作成しない限り、ecj で動作します。

package test;

import java.util.Optional;
import java.util.function.Supplier;

public class B {
    public static void main(String[] args) {

        // This works fine:
        System.out.println(new Object() {
            int j = 5;
        }.j);

        // This also
        System.out.println(trace(new Object() {
            int j = 5;
        }).j);

        // Also no problem
        System.out.println(unwrapAndTrace(Optional.of(new Object() {
            int j = 5;
        })).j);

        // Lambdas work:
        System.out.println(((Supplier & Serializable) () -> new Object()).get()); 

        // This doesn't work.
        System.out.println(invokeAndTrace(() -> new Object() {
            int j = 5;
        }).j);
    }

    public static <T> T trace(T obj) {
        System.out.println(obj);
        return obj;
    }

    public static <T> T invokeAndTrace(Supplier<T> supplier) {
        T result = supplier.get();
        System.out.println(result);
        return result;
    }

    public static <T> T unwrapAndTrace(Optional<T> optional) {
        T result = optional.get();
        System.out.println(result);
        return result;
    }


}
4

1 に答える 1

8

これは ecj のバグで、最近Bug 535969として報告されました。

簡単に言うと、難しい技術的な問題を回避するために、コンパイラは型の推論中に匿名クラスを削除し、それをそのスーパー クラスに置き換えます (常にではありませんが、特定の状況で)。これにより、実際に匿名クラスを使用する必要がある場合の結果mapToObj()が表示されます。Stream<Object>この情報の損失は問題ないという元の評価 (誰も匿名クラスについて言及できないため) は、この質問の例によって間違っていることが証明されています。

編集: バグは、既存のレポートバグ 477894によって修正されました。

于 2018-06-23T13:42:13.737 に答える