标题名称可能措辞不当,并且知识渊博的人可以对其进行编辑。
我想创建一种方法parseFromJSONMap
,该方法使用gson解析JSON文件并将数据作为Map返回,更具体地说,是Map<String, T>
,其中T是名为Entity
的类的子类。到目前为止,定义了两个子类,分别为Creature
和Hero
,但以后可能还会更多。所以如果我打电话
parseFromJSONMap(file, Creature.class)
它应该返回一个
Map<String, Creature>
,如果我打电话parseFromJSONMap(file, Hero.class)
它应该返回
Map<String, Hero>
等。这就是现在的方法(仅适用于Creatures):
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
上调用任何方法(例如test.get("someCreature")
)时,将发生异常,因此这是运行时异常。 最佳答案
您是说要这样做才能使它炸毁吗?
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时需要使type参数具体化,否则如何知道它应该表示什么类型?请记住,擦除是replacing type parameters by their leftmost bound,而super type token(这是TypeToken的含义,在Guice&Gson和其他地方使用)基本上是一种技巧,使您可以通过以下方式访问超类的参数化类型信息反射。还要注意javadoc说
此语法不能用于创建具有通配符的类型文字
参数,例如
Class<?>
或List<? extends> CharSequence>
。这基本上是您的情况。我知道的唯一出路是通过编程方式创建类型令牌。例如,通过
Method.getGenericReturnType
或通过查看Guice使用类型令牌的方式,乍一看,它具有一组更丰富的实用程序方法来弄清楚这些内容。如何执行此操作的示例在this question中,该示例使用了一些guice类,但是如果您查看guice源,那么正在发生的事情应该变得相当明显。