0

指定された特定のタイプのコレクションを作成するために使用できる次のメソッドがあるとします。

private static Collection<?> void create(Class<? extends Collection<?>> cls) {
    return cls.newInstance();
}

実行時に cls 引数が渡される場合、これはすべて問題ありません。

List<String> list = new LinkedList<String>();
create(list.getClass());

しかし、チェックされていない警告なしでコードでこのメソッドを呼び出すにはどうすればよいでしょうか? 次のようなことをしたいとします。

create(LinkedList.class);

create(Class) が定義されていないと不平を言うでしょう。List は Collection の #capture ではないため、厳密に言えば正しいのですが、どうすればそれを機能させることができますか?

どうもありがとう!

4

2 に答える 2

3

Neal Gafter は、この問題についてほぼ正確にここで語っています。修正は、スーパー タイプ トークンを使用することです。これは、Guice がジェネリック型情報を維持するために使用するものだと思います。

基本的に、これは を使用する代わりに型を表すために使用できる追加のクラスですFoo.class。次のように使用します。

TypeReference<LinkedList<String>> x = new TypeReference<LinkedList<String>>() {};
create(x);

生の型を使用しようとするLinkedListと、コンパイラが不平を言うことに注意してください。生の型を使用すると、基本的に型の安全性をオプトアウトすることになります。しかし、このスキームを使用すると、他の方法では難しい方法でジェネリック型を表現できます。

于 2010-09-21T05:52:56.047 に答える
0

ここには2つのジェネリック型があります。1つはコレクションのサブタイプ用で、もう1つはコレクションの要素タイプ用です。次のコードが機能します。

private static <C extends Collection<E>, E>
C create(Class<C> cls) throws Exception
{
    return cls.newInstance();
}

使用例。警告はありません。

    Class<LinkedList<String>> clazz = ...;
    LinkedList<String> result = create(clazz);

問題は、どうやって入手するclazzかということです。コンパイラを本当に一生懸命説得する必要があります。

    List<String> list = new LinkedList<String>();
    clazz = (Class<LinkedList<String>>)list.getClass();

    clazz = (Class<LinkedList<String>>)(Class<?>)LinkedList.class;

型キャストを容易にするユーティリティメソッドを使用できます。

public static <C extends Collection, E, T extends Collection<E>>
Class<T> type(Class<C> classC, Class<E> classE)
{
    return (Class<T>)classC;
}

//usage:
    clazz = type(LinkedList.class, String.class);
    result = create(clazz);

楽しみは再帰的です:

    Class<LinkedList<LinkedList<String>>> clazz2;
    LinkedList<LinkedList<String>> result2;

    clazz2 = type(LinkedList.class, clazz);
    result2 = create(clazz2);

しかし、ある時点で、このばかげたゲームをやめなければなりません。ジェネリックタイピングは、私たちを苦しめるのではなく、私たちを助けることになっています。面倒になりすぎてプログラムが読めなくなったら、ドロップしてください。私たちが何年も幸せに暮らしてきた生のタイプを使ってください。

于 2010-09-21T17:17:58.043 に答える