反序列化Gson中的通用列表

我想编写一个generics函数,用Gson反序列化generics类型List,代码如下:

private  List GetListFromFile(String filename) { //Read textfile BufferedReader reader; String data=""; try { reader = new BufferedReader(new FileReader(filename)); data = reader.readLine(); reader.close(); } catch (FileNotFoundException ex) { } catch (IOException ex) { } if (data == null) { List Spiel = new ArrayList(); return Spiel; } else { //get list with Deserialise Gson gson = new Gson(); List something = gson.fromJson(data, new TypeToken<List>(){}.getType()); return something; } } 

但这段代码不起作用,我得到一个奇怪的结构,但不是我的类型列表

当我使用时:

 List something = gson.fromJson(data, new TypeToken<List>(){}.getType()); 

我工作我得到一个List !!

但我需要一个通用function,我该如何解决?

关心rubiktubik

没有将实际类型的T (如Class )传递给您的方法,就无法做到这一点。

但是如果你明确地传递它,你可以为List创建一个TypeToken ,如下所示:

 private  List GetListFromFile(String filename, Class elementType) { ... TypeToken> token = new TypeToken>() {}; List something = gson.fromJson(data, token.getType()); ... } 

也可以看看:

  • TypeToken

使用TypeToken的方法不起作用。

 new TypeToken>() 

因为generics(类型擦除)和reflection的工作方式是不可能的。 整个TypeToken hack有效,因为Class#getGenericSuperclass()执行以下操作

返回表示此Class表示的实体(类,接口,基本类型或void)的直接超类的Type。

如果超类是参数化类型,则返回的Type对象必须准确反映源代码中使用的实际类型参数。

换句话说,如果它看到ArrayList ,那么它将返回ParameterizedType ,你将无法提取类型变量T将具有的编译时间值。

TypeParameterizedType都是接口。 您可以提供自己实现的实例。

所以,你有两个选择:

选项1:自己实现java.lang.reflect.ParameterizedType并将其传递给Gson。

 private static class ListParameterizedType implements ParameterizedType { private Type type; public ListParameterizedType(Type type) { this.type = type; } @Override public Type[] getActualTypeArguments() { return new Type[] {type}; } @Override public Type getRawType() { return ArrayList.class; } @Override public Type getOwnerType() { return null; } // implement equals method too! (as per javadoc) } 

那简单地说:

 Type type = new ListParameterizedType(clazz); List list = gson.fromJson(json, type); 

请注意,根据javadoc ,还应实现equals方法。

选项2:手动解析列表,然后为每个元素使用Gson

 public  List listEntity(Class clazz) throws WsIntegracaoException { try { // Consuming remote method String strJson = getService().listEntity(clazz.getName()); JsonParser parser = new JsonParser(); JsonArray array = parser.parse(strJson).getAsJsonArray(); List lst = new ArrayList(); for(final JsonElement json: array){ T entity = GSON.fromJson(json, clazz); lst.add(entity); } return lst; } catch (Exception e) { throw new WsIntegracaoException( "WS method error [listEntity()]", e); } }