使用Gson将Json解析为具有通用字段的项目列表 [英] Parsing Json to List of Items with generic field with Gson

查看:313
本文介绍了使用Gson将Json解析为具有通用字段的项目列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class OwnCollection< T> {
private int size;
私人列表< ResponseItem< T>>数据;
}

public class ResponseItem< T> {
private String path;
私人字符串键;
私人T值;
}

公共类查询{
public< T> OwnCollection< T> getParsedCollection(...){
String json = ...; //一些不重要的调用,我得到一个有效的Json来解析
return Result。< T> parseToGenericCollection(json);
}
}

公共类结果{
public static< T> OwnCollection< T> parseToGenericCollection(String result){
Type type = new TypeToken< OwnCollection< T>>(){} .getType();
// GsonUtil是一个我得到实例Gson的类,仅此而已。
返回GsonUtil.getInstance()。fromJson(result,type);


现在我怎么称呼它:

  OwnCollection< Game> gc = new Query()。< Game> getParsedCollection(...); 

结果我想,我会得到 OwnCollection 带有 List< ResponseItem> ,其中一个Response Item包含类 Game 的字段。 Json非常好,没有解析错误,现在唯一的问题就是当我尝试获取一个游戏项目并调用方法时出现此错误:

 线程main中的异常java.lang.ClassCastException:com.google.gson.internal.LinkedTreeMap无法转换为at.da.example.Game 


解决方案

代码

  OwnCollection< Game> gc = new Query()。< Game> getParsedCollection(...); 

实际上不会传递游戏里面 getParsedCollection()< Game> 这里只告诉编译器 getParsedCollection()应该返回 OwnCollection< ;游戏> ,但 T getParsedCollection()(和 parseToGenericCollection())仍然被擦除,因此 TypeToken 无法帮助您捕获其值。



您需要传递 Game.class 作为参数

  public< T> OwnCollection< T> getParsedCollection(Class< T> elementType){...} 
...
OwnCollection< Game> gc = new Query()。getParsedCollection(Game.class);

然后使用 TypeToken 链接 OwnCollection T elementType 如下:



$ p $ Type type = new TypeToken< OwnCollection< T>>(){}
.where(new TypeParameter< T>() {},elementType)
.getType();

请注意,此代码使用 来自Guava的TypeToken ,因为<$ c来自Gson的$ c> TypeToken 不支持此功能。


public class OwnCollection<T>{
    private int size;
    private List<ResponseItem<T>> data;
}

public class ResponseItem<T>{
    private String path;
    private String key;
    private T value;
}

public class Query{
    public <T> OwnCollection<T>  getParsedCollection( ... ){
        String json = ...; //some unimportant calls where I get an valid Json to parse
        return Result.<T>parseToGenericCollection(json);
    }
}

public class Result{
    public static <T> OwnCollection<T> parseToGenericCollection(String result){
        Type type = new TypeToken<OwnCollection<T>>() {}.getType();
        //GsonUtil is a class where I get an Instance Gson, nothing more.
        return GsonUtil.getInstance().fromJson(result, type);
    }
}

Now how I call it:

OwnCollection<Game> gc = new Query().<Game>getParsedCollection( ... );

As result I thought, I will get a OwnCollection with a List<ResponseItem> where one Response Item contains a field of the class Game. The Json is perfectly fine and there is no parsing error the only problem now is this error when I try to get one Game item and call a method:

Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to at.da.example.Game

解决方案

It doesn't work this way, because the following code

OwnCollection<Game> gc = new Query().<Game>getParsedCollection( ... );

actually doesn't pass Game inside getParsedCollection(). <Game> here only tells the compiler that getParsedCollection() is supposed to return OwnCollection<Game>, but T inside getParsedCollection() (and parseToGenericCollection()) remains erased, therefore TypeToken cannot help you to capture its value.

You need to pass Game.class as a parameter instead

public <T> OwnCollection<T> getParsedCollection(Class<T> elementType) { ... }
...
OwnCollection<Game> gc = new Query().getParsedCollection(Game.class);

and then use TypeToken to link OwnCollection's T with elementType as follows:

Type type = new TypeToken<OwnCollection<T>>() {}
    .where(new TypeParameter<T>() {}, elementType)
    .getType();

Note that this code uses TypeToken from Guava, because TypeToken from Gson doesn't support this functionality.

这篇关于使用Gson将Json解析为具有通用字段的项目列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆