3

Eclipse ビルドから Maven ビルドに移行したときに、プロジェクトで多くの問題を発見しました。2.5.1 コンパイラ プラグインを使用します。

JDKはopen-JDK-7です

私は新しいプロジェクトで問題を分離し、問題を解決しました。これは次のとおりです。

public class Test {

public static void main(String[] args) {
    List<String> list = newList();
    for(String name : sort(newList(list))) {
        System.out.println(name);
    }
}

public static <T> List<T> newList() {
    return new ArrayList<T>();
}

public static <T, E extends T> List<T> newList(Collection<E> list) {
    return new ArrayList<T>();
}

public static <T> List<T> sort(List<T> list) {
    return list;
}
}

これは javaC でのコンパイルに失敗します (ただし、Eclipse では動作します)。次のエラーが表示されます。

[エラー] プロジェクト テストで目標 org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile) を実行できませんでした: コンパイルの失敗
[エラー] /home/username/workspaces/projectx43/test /src/main/java/test/Test.java:[11,24] エラー: 互換性のない型

そして、これはうまくいきます:

public class Test {

    public static void main(String[] args) {
        List<String> list = newList();
        for(String name : sort(newList(list))) {
            System.out.println(name);
        }
    }

    public static <T> List<T> newList() {
        return new ArrayList<T>();
    }

    public static <T> List<T> newList(Collection<? extends T> list) {
        return new ArrayList<T>();
    }

    public static <T> List<T> sort(List<T> list) {
        return list;
    }
}

E を使用したバージョンは、T のみを使用したバージョンと同じくらい優れていることがわかります。ここでの問題は、これを受け入れるように javac コンパイラを微調整できるかということです。これに関する情報をいただければ幸いです。

また別の可能性: openJDK 7 はこれを SunJDK 7 とは異なる方法で処理していますか? このスニペットを最新の Windows Sun JDK 7 バージョンまたは JDK 8 のベータ版で確認してください。どうもありがとうございました。

PS: Eclipse vs. JavaC + Generics の質問を読みましたが、リンクされているバグは解決済みであると述べています。

4

1 に答える 1

3

2008 年に Java 5.0 を採用したときも、まったく同じ問題があったことを思い出しました。これは、Eclipse コンパイラーがジェネリックをわずかに異なる方法で処理するという事実に関連しています。

上記の例を確認すると、JavaC コンパイラは推移的なジェネリックの解決を許可していません。例として、これを見てみましょう:

List<String> strings = sort(newList("A", "B", "C");

ここで JavaC は、並べ替えが List に適用できないと文句を言います。

<T> List<T> sort(List<T>) {...};
<T> List<T> newList(T ... elements) {};

解決策は、上記の式の美しさを損なう変数を導入することです。

List<String> list = newList("A", "B", "C");
List<String> strings = sort(list);

これがエラーであると予想されるかどうかによって異なります。Eclipse コンパイラ バージョンの方が式が読みやすいので気に入っています。

于 2013-11-09T22:59:18.760 に答える