JavaジェネリックのフォローアップとしてEclipseでコンパイルしますが、javacではコンパイルしないため、Eclipseで正常にコンパイルおよび実行されるが、javacでコンパイルエラーが発生する別のスニペットを投稿します。(これにより、スニペットが抽出されたプロジェクトがMavenでビルドされなくなります。)
自己完結型のスニペット:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Foo<?>> setOfFoos = new HashSet<Foo<?>>();
List<Foo<?>> sortedListOfFoos = asSortedList(setOfFoos);
}
public static <T extends Comparable<T>> List<T> asSortedList(Collection<T> c) {
List<T> list = new ArrayList<T>(c);
java.util.Collections.sort(list);
return list;
}
public static class Foo<T> implements Comparable<Foo<T>> {
@Override
public int compareTo(Foo<T> o) {
return 0;
}
}
}
javacでのコンパイルは以下を返します:
Main.java:11: <T>asSortedList(java.util.Collection<T>) in Main cannot be applied to (java.util.Set<Main.Foo<?>>)
List<Foo<?>> sortedListOfFoos = asSortedList(setOfFoos);
^
上記のスニペットに置き換えるとFoo<?>
、Foo<String>
javacでコンパイルされます。これは、問題が使用されているワイルドカードに関連していることを意味します。Eclipseコンパイラはより耐性があると思われるので、スニペットが有効なJavaではない可能性はありますか?
(私はjavac1.6.0_37とEclipseIndigoをコンパイラコンプライアンスレベル1.6で使用しています)
(EDIT1:EDIT2で削除された別の例が含まれています。)
EDIT2 :評判が悪く、比較することは概念的に間違っている可能性があり、sehの答えに触発されてFoo<A>
、作業は次のように書くことができます。Foo<B>
asSortedFooList
public static <T extends Foo<?>> List<T> asSortedFooList(Collection<T> c) {
List<T> list = new ArrayList<T>(c);
java.util.Collections.sort(list);
return list;
}
Comparable<T>
(上記のメソッド定義でのwithの単純な置換Foo<?>
。)したがって、javacとimhoは、概念的にanyFoo<A>
とを比較するのが安全であるように思われますFoo<B>
。asSortedList
ただし、その型引数がワイルドカードでパラメーター化されている場合、ジェネリックコレクションのソートされたリスト表現を返すジェネリックメソッドを作成することはまだできません。Foo<?>
で置換してjavacを「だまそう」としS extends Comparable<S>
ましたasSortedFooList
が、これは機能しませんでした。
EDIT3:後でラファエルComparable<Foo<T>>
は、実装は必要ないので設計に欠陥があることを指摘し、実装Comparable<Foo<?>>
は同じ機能を提供し、洗練された設計によって最初の問題を解決します。
(最初の理由と利点は、aがその具体的なタイプFoo<T>
を気にしないかもしれないが、それでも具体的なタイプのインスタンスを使用する可能性があることでしT
た。他の目的のためにインスタンス化されます。そのインスタンスは、を決定するために使用する必要はありません。Foo
APIの他の部分で使用される可能性があるため、他のsの中で順序付けします。
具体的な例:各Fooが。の異なる型引数でインスタンス化されると仮定しますT
。のすべてのインスタンスには、 -methodの実装で使用されるFoo<T>
タイプの増分IDがあります。これで、これらの異なる型のリストを並べ替えることができ、具象型を気にせず(で表現)、後で処理するために具象型のインスタンスにアクセスできます。)int
compareTo
Foo
T
Foo<?>
T