Gson TypeToken with dynamic ArrayList item type
我有以下代码:
1 2 | Type typeOfObjectsList = new TypeToken<ArrayList<myClass>>() {}.getType(); List<myClass> objectsList = new Gson().fromJson(json, typeOfObjectsList); |
它将JSON字符串转换为对象的
但是现在我想让此
我尝试了这个:
1 2 3 4 | private < T > Type setModelAndGetCorrespondingList2(Class< T > type) { Type typeOfObjectsListNew = new TypeToken<ArrayList< T >>() {}.getType(); return typeOfObjectsListNew; } |
但这是行不通的。 这是例外:
1 |
从Gson 2.8.0开始,您可以使用
例如:
1 |
您提出的语法无效。下列
1 | new TypeToken<ArrayList<Class.forName(MyClass)>> |
之所以无效,是因为您尝试传递期望类型名称的方法调用。
下列
1 | new TypeToken<ArrayList< T >>() |
由于泛型(类型擦除)和反射的工作方式,因此无法实现。整个
Returns the Type representing the direct superclass of the entity
(class, interface, primitive type or void) represented by this Class.If the superclass is a parameterized type, the Type object returned
must accurately reflect the actual type parameters used in the source
code.
换句话说,如果它看到
选项1-自己实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | private static class ListParameterizedType implements ParameterizedType { private Type type; private 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) } |
然后简单地:
1 2 | Type type = new ListParameterizedType(clazz); List< T > list = gson.fromJson(json, type); |
请注意,按照javadoc,equals方法也应实现。
选项2-(不要这样做)重用gson内部...
至少在Gson 2.2.4中也可以使用。
1 | Type type = com.google.gson.internal.$Gson$Types.newParameterizedTypeWithOwner(null, ArrayList.class, clazz); |
您可以使用番石榴功能更强大的
1 2 3 4 5 | private static < T > Type setModelAndGetCorrespondingList2(Class< T > type) { return new TypeToken<ArrayList< T >>() {} .where(new TypeParameter< T >() {}, type) .getType(); } |
这对我有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public < T > List< T > listEntity(Class< T > clazz) throws WsIntegracaoException { try { // Consuming remote method String strJson = getService().listEntity(clazz.getName()); JsonParser parser = new JsonParser(); JsonArray array = parser.parse(strJson).getAsJsonArray(); List< T > lst = new ArrayList< T >(); 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); } } |
1 2 |
可以与地图和任何其他集合一起使用:
这是一个不错的演示,您如何在自定义反序列化器中使用它:
使用Gson反序列化ImmutableList
您实际上可以做到。您只需要先将数据解析为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Class< T > dataType; //... JsonElement root = jsonParser.parse(json); List< T > data = new ArrayList<>(); JsonArray rootArray = root.getAsJsonArray(); for (JsonElement json : rootArray) { try { data.add(gson.fromJson(json, dataType)); } catch (Exception e) { e.printStackTrace(); } } return data; |