5

次の方法を想定しましょう (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);
}

ありがとう。

4

2 に答える 2

6

この質問に対する満足のいく答えはありません。無制限のワイルドカードでパラメータ化された型のクラス リテラルは、理論的にはうまくいくだけで、私たちにはありません。

Class<Abc<?>>型指定されたクラス オブジェクトを未チェックのキャストで生成し、それをユーティリティ メソッドまたはフィールドに移動できます。がほとんどない限りAbc、これは非常にうまく機能します。

@SuppressWarnings("unchecked")
public static Class<Abc<?>> ABC = (Class<Abc<?>>)(Object) Abc.class;
于 2012-06-03T12:04:21.427 に答える
0

これがコンパイルされることがわかりました..

public static <T> Iterable<Abc<T>> myFilter (Iterable<Abc<T>> myIterator) {
    Class<Abc<T>> myClass = null;
    Iterable<Abc<T>> a3 = Iterables.filter(myIterator, myClass); 
    return a3;
}

しかし、同じ問題をmyFilter()の呼び出し元に移すだけです。ベン・シュルツが正しい答えを持っていると思います。

于 2012-06-03T11:40:00.797 に答える