14

Javaで次のようなことをする方法があるかどうか疑問に思っていました

Class c = List<String>.class;
Class c2 = List<Date>.class;

クラス名 (ジェネリック型) と、後で検索できる対応するオブジェクトを格納するマップを作成するには、このようなものが必要です。例えば、

Map<Class, Object> dataMap = new HashMap<Class, Object>();
dataMap.put(c, listOfStrings);
dataMap.put(c2, listOfDates);

実行時の型消去のためにこれは不可能ですか?

4

3 に答える 3

15

このようにすることはできませんが、Guice がTypeLiteral. 既に Guice を使用している場合は、それを直接使用することをお勧めします。それ以外の場合は、独自の同様のクラスを作成することをお勧めします。

本質的には、型引数を指定するジェネリック型のサブクラスがその情報を直接保持するという考え方です。したがって、次のように記述します。

TypeLiteral literal = new TypeLiteral<List<String>>() {};

literal.getClass().getGenericSuperclass()次に、それから型引数を使用および取得できます。それ自体は、興味深いコードを持つ必要はありません (他の理由で、Guice に何かがTypeLiteralあるかどうかはわかりません) 。

于 2012-04-21T08:33:39.533 に答える
5

いいえ、できません。コード内でを参照することさえできませんList<String>.class。コンパイル エラーが発生します。には 1 つのクラス オブジェクトしかなくList、それは と呼ばれList.classます。

実行時の型消去のためにこれは不可能ですか?

正しい。

ところで、これは注釈付きの型ではなく、ジェネリック型です。

アップデート

よく考えてみると、Josh Bloch のタイプセーフな異種コンテナー( Effective Java 2nd Ed.、Item 29で公開) を少し調整することで、上記の Map にかなり近いものを作成できます。

public class Lists {
    private Map<Class<?>, List<?>> lists =
            new HashMap<Class<?>, List<?>>();

    public <T> void putList(Class<T> type, List<T> list) {
        if (type == null)
            throw new NullPointerException("Type is null");
        lists.put(type, list);
    }

    public <T> List<T> getList(Class<T> type) {
        return (List<T>)lists.get(type);
    }
}

キャストインgetListはチェックされず、警告が表示されますが、残念ながらそれを回避することはできません。ただし、コンパイラによって保証されているため、 class に格納される値は でXなければならないことがわかっています。List<X>したがって、キャストは安全だと思います(ルールに従ってプレイする場合、つまりputList、プレーンな非ジェネリックClassパラメーターで呼び出すことはありません)。したがって、を使用して抑制できます@SuppressWarnings("unchecked")

そして、次のように使用できます。

Lists lists = new Lists();
List<Integer> integerList = new ArrayList<Integer>();
List<String> stringList = new ArrayList<String>();
...

lists.putList(Integer.class, integerList);
lists.putList(String.class, stringList);
List<Integer> storedList = lists.getList(Integer.class);

assertTrue(storedList == integerList);
于 2012-04-21T08:28:48.107 に答える
1

あなたがしようとしているようにそれは不可能です。
ただし、これらのリストを装飾MyListDatesして、MyListString代わりに and を作成し、ハッシュマップに保存することもできます

于 2012-04-21T08:31:02.037 に答える