9

ジェネリックが導入されてから、Class はパラメータ化され、List.class は Class<List> を生成します。これは明らかです。

私が理解できないのは、それ自体がパラメータ化されたタイプの Class のインスタンス、つまり Class<List<String>> を取得する方法です。このスニペットのように:

public class GenTest {
    static <T> T instantiate(Class<T> clazz) throws Exception {
        return clazz.newInstance();
    }
    public static void main(String[] args) throws Exception {
        // Is there a way to avoid waring on the line below
        // without using  @SuppressWarnings("unchecked")?
        // ArrayList.class is Class<ArrayList>, but I would like to
        // pass in Class<ArrayList<String>>
        ArrayList<String> l = GenTest.instantiate(ArrayList.class);
    }
}

私はこの問題のバリエーションにかなり頻繁に出くわしますが、何かを見落としているだけなのか、それとも本当に良い方法がないのか、まだわかりません。提案をありがとう。

4

4 に答える 4

8

Class クラスは、型の実行時表現です。パラメータ化された型は実行時に型消去を受けるため、Class のクラス オブジェクトは Class<List<Integer>> および Class<List<String>> の場合と同じになります。

.class 表記を使用してそれらをインスタンス化できない理由は、これがクラス リテラルに使用される特別な構文であるためです。Java 言語仕様では、型がパラメーター化されている場合にこの構文を明確に禁止しています。これが List<String>.class が許可されていない理由です。

于 2008-09-16T12:35:42.310 に答える
1

クラスは、生の型であるクラスローダーによってロードされたクラスを表します。パラメータ化された型を表すには、java.lang.reflect.ParameterizedType を使用します。

于 2008-09-16T12:43:09.967 に答える
1

あなたがしようとしていることができるとは思いません。まず、インスタンス化メソッドは、パラメーター化された型を扱っていることを認識していません (java.util.Date.class を簡単に渡すことができます)。第 2 に、消去のために、実行時にパラメーター化された型で特に具体的なことを行うことは困難または不可能です。

別の方法で問題にアプローチする場合は、型推論など、他の小さなトリックを実行できます。

public class GenTest
{
    private static <E> List<E> createList()
    {
        return new ArrayList<E>();
    }

    public static void main(String[] args)
    {
        List<String> list = createList();
        List<Integer> list2 = createList();
    }
}
于 2008-09-16T12:43:22.870 に答える
0

あなたができる唯一のことは、List<String> 直接インスタンス化してそのを呼び出すことgetClass()です:

instantiate(new List<String>() { ... }.getClass());

のような複数の抽象メソッドを持つ型の場合List、これは非常に厄介です。しかし残念ながら、サブクラス コンストラクター ( などnew ArrayList<String>) やファクトリ メソッド ( Collections.<String>emptyList()) の呼び出しは機能しません。

于 2012-11-13T17:04:13.117 に答える