是否可以将通用参数发送到Map?

时间:2011-10-23 19:25:51

标签: java json generics gson

也许标题措辞严厉,知识渊博的人可以编辑它。

我想创建一个方法parseFromJSONMap,它使用gson解析JSON文件并将数据作为Map返回,更具体地说是Map<String, T>,其中T是名为{{1}的类的子类}。到目前为止,已定义了两个子类EntityCreature,但稍后可能会有更多。所以,如果我打电话

Hero

如果我致电

,它应该返回parseFromJSONMap(file, Creature.class)
Map<String, Creature>

它应该返回parseFromJSONMap(file, Hero.class) 等。

这就是现在的方法(它只适用于Creatures):

Map<String, Hero>

因此,我想放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); } 而不是Creature。如果我这样做并称之为

T

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

我想要的是什么?

编辑:当我在java.lang.Object cannot be cast to heroes.model.Creature上调用任何方法时发生异常,例如test,因此这是一个运行时异常。

1 个答案:

答案 0 :(得分: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(这是TypeToken的用途,如Guice&amp; Gson和其他各种地方所使用的)基本上是一种技巧,可让您访问参数化类型通过反射的超类信息。另请注意javadoc说

  

此语法不能用于创建具有通配符的类型文字   参数,例如Class<?>List<? extends> CharSequence>

这基本上就是你的情况。我所知道的唯一出路就是以编程方式创建类型令牌。例如,通过Method.getGenericReturnType或通过查看Guice使用类型令牌的方式,乍一看它有更丰富的实用方法来计算这些东西。如何执行此操作的一个示例是this question,这使用了一些guice类,但是如果你看一下guice源,那么它应该变得相当明显。