也许标题措辞严厉,知识渊博的人可以编辑它。
我想创建一个方法parseFromJSONMap
,它使用gson解析JSON文件并将数据作为Map返回,更具体地说是Map<String, T>
,其中T是名为{{1}的类的子类}。到目前为止,已定义了两个子类Entity
和Creature
,但稍后可能会有更多。所以,如果我打电话
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
,因此这是一个运行时异常。
答案 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源,那么它应该变得相当明显。