次の方法を想定しましょう (Guava の Iterables から):
public static <T> Iterable<T> filter(final Iterable<?> unfiltered, final Class<T> type) {
return null;
}
そしてこのコレクション:
Set<?> objs = ...;
次に、次のコードがコンパイルされ、ジェネリックが正しく派生されます
Iterable<String> a2 = Iterables.filter(objs, String.class);
(Guava では、これは 内のすべての文字列の iterable を返しobjs
ます。)
しかし、次のクラスを想定してみましょう。
static class Abc<E> {
E someField;
}
filter
呼び出して取得する方法がわかりませんIterable<Abc<?>>
:
Iterable<Abc> a3 = Iterables.filter(objs, Abc.class);
Iterable<Abc<?>> a4 = Iterables.filter(objs, Abc.class); // Compile error - Abc and Abc<?> are incompatible types
Iterable<Abc<?>> a5 = Iterables.filter(objs, Abc<?>.class); // Compile error
Iterable<Abc<?>> a6 = Iterables.<Abc<?>>filter(objs, Abc.class); // Compile error
Iterable<Abc<?>> a7 = (Iterable<Abc<?>>) Iterables.filter(objs, Abc.class); // Compile error - inconvertible types
Iterable<Abc<?>> a8 = Iterables.filter(objs, new Abc<?>().getClass()); // Compile error
Iterable<Abc<?>> a8a = Iterables.filter(objs, new Abc<Object>().getClass()); // Compile error
a3 のみがコンパイルされますが、Abc にパラメーターがないため、後続のコードでジェネリック型のチェックが行われません。
型パラメーターが実行時に存在しないことを知っているため、次のようなコードを記述しようとしません。
Iterable<Abc<String>> a9 = Iterables.filter(objs, Abc<String>.class); // Compile error
タイプ Abc (a3 のように) のすべてのオブジェクトをフィルター処理したいだけですが、結果にジェネリック パラメーターが含まれています。私が見つけたこれを行う唯一の方法は、ばかげている次のとおりです。
Iterable<Abc<?>> a10 = new HashSet<Abc<?>>();
for (Abc<?> a : Iterables.filter(objs, Abc.class)) {
((Set<Abc<?>>)a10).add(a);
}
ありがとう。