2011-10-23 5 views
2

おそらく、タイトルはひどく言い表されており、より良い知識を持つ人がそれを編集する可能性があります。ジェネリックパラメータをマップに送ることはできますか?

私はgsonを使用してJSONファイルを解析し、地図、TはEntityというクラスにサブクラスであり、より具体的Map<String, T>としてデータを返すメソッドparseFromJSONMapを作成したいです。サブクラスのうちの2つは今までに定義されており、CreatureHeroですが、それ以上の場合があります。だから私は

parseFromJSONMap(file, Creature.class) 

を呼び出す場合には、Map<String, Creature>を返す必要がありますし、私は

それはMap<String, Hero>などを返すべき

parseFromJSONMap(file, Hero.class) 

を呼び出す場合、このメソッドは、今(それだけで作品のように見えるものです生物のため):

public static <T extends Entity> Map<String, T> parseFromJSONMap(File file, Class<T> clazz) throws FileNotFoundException 
{ 
    Type type = new TypeToken<HashMap<String, Creature>>(){}.getType(); 
    return gson.fromJson(new FileReader(file), type); 
} 

したがって、の代わりに、Tを入れたい。私はそれを行うので、

Map<String, Creature> test = Entity.parseFromJSONMap(somefile, Creature.class); 

のようにそれを呼び出すと、私はjava.lang.Object cannot be cast to heroes.model.Creature

取得私が可能欲しいものですか?

編集:testのいずれかのメソッドを呼び出すと例外が発生します。たとえば、test.get("someCreature")です。これは実行時例外です。

+0

あなたが得たstacktraceを追加する価値があります – Matt

+0

私が持っているものはすべて、 'Entity.parseFromJSONMap'を呼び出す' Creature'の一時的なmainメソッドなので、私が得る例外は私だけだと思います。 'main"スレッドの例外java.lang.ClassCastException:java.lang.Objectはheroes.model.Creature.main(heroes.model.Creature.main)にあるheroes.model.Creatureにキャストできません。 \tjava:131) ' –

答えて

1

あなたはこれを吹き飛ばしてしまうのですか?

public static <T extends Entity> Map<String, T> parseFromJSONMap(File file, Class<T> clazz) throws FileNotFoundException 
{ 
    Type type = new TypeToken<HashMap<String, T>>(){}.getType(); 
    return gson.fromJson(new FileReader(file), type); 
} 

あなたの問題は、あなたがTypeTokenを作成するときに型引数コンクリートを作るために必要があるとそうでない場合はどのようにそれが表現すべきかのタイプを知ることができますか?消去はreplacing type parameters by their leftmost boundで、super type token(Guice & Gsonやその他のさまざまな場所で使用されているように、そのTypeTokenは基本的には、リフレクションによってスーパークラスのパラメータ化された型情報にアクセスすることができます)。また

を言うJavadocを注意この構文は、このようなClass<?>List<? extends> CharSequence>としてワイルドカード パラメータを持っているタイプのリテラルを作成するために使用することはできません。

これは基本的にあなたの状況です。私が知っている唯一の方法は、プログラマチックにタイプトークンを作成することです。たとえば、Method.getGenericReturnTypeを経由したり、Guiceがタイプトークンを使用する方法を見てみると、一見すると、このものを見つけるための豊富なユーティリティメソッドが用意されています。これを行う方法の例はthis questionですが、これはいくつかのguiceクラスを使用しますが、guiceソースを見ると、何が起こっているのかが合理的に明らかになるはずです。

+0

私は必要以上にライブラリを追加したくありません。 'parseFromJSONMap'をエンティティの法線マップを返す抽象メソッドとし、それを各サブクラスに実装させると意味がありますか? –

+0

は、作成しているタイプを常に制御するという条件付きで、問題を解決する簡単で冗長な方法です。唯一の選択肢は、この機能を提供するために使用しているライブラリを拡張しているようです。 – Matt

+0

これは私が「抽象的な静的」修飾子を使用したい場合の1つだと思います。 私は一時的にすべてを開始するGameResourceManagerクラスを持つことで問題を解決しました。 GRMはまずcreaturesフォルダ内の各jsonファイルを解析してCreaturesを表現し、次にHeroesなどを表す英雄フォルダに入れます。これは良いデザインかどうかわかりませんが、個々のクラスの責任を単一のクラスに移しますあなたが言うように、私はおそらく、私が作成しているタイプをより詳細に制御するでしょう。 –

関連する問題