使用 GSON 反序列化泛型类型

2022-08-31 15:02:19

我在Android应用程序中实现Json反序列化时遇到了一些问题(使用Gson库)

我像这样上课

public class MyJson<T>{
    public List<T> posts;
}

反序列化调用是:

public class JsonDownloader<T> extends AsyncTask<Void, Void, MyJson<T>> {
...
protected MyJson<T> doInBackground(Void... params) {
  ...
    Reader reader = new InputStreamReader(content);
    GsonBuilder gson = new GsonBuilder();
    Type collectionType = new TypeToken<MyJson<T>>() {}.getType();
    result = gson.create().fromJson(reader, collectionType);
  ...
  }
}

问题是 result.posts 列表在调用后包含一个 LinkedTreeMap 对象数组(具有正确的值,因此问题是反序列化)而不是 MyJson 对象。当我使用MyObject而不是T时,一切都运行良好,MyObject是正确的。

那么有没有办法在不创建自定义反序列化程序的情况下实现反序列化调用呢?


答案 1

您必须在反序列化时指定 的类型。如果不知道要实例化什么,您将如何创建?它不能永远存在。因此,您需要将类型作为参数提供。TListpostsGsonTypeTTClass

现在假设,的类型是你反序列化的(为了简单起见,我还添加了一个参数;你会像以前一样从你的中读取):postsStringMyJson<String>String jsonreader

doInBackground(String.class, "{posts: [\"article 1\", \"article 2\"]}");

protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {

    GsonBuilder gson = new GsonBuilder();
    Type collectionType = new TypeToken<MyJson<T>>(){}.getType();

    MyJson<T> myJson = gson.create().fromJson(json, collectionType);

    System.out.println(myJson.getPosts()); // ["article 1", "article 2"]
    return myJson;
}

同样,要反序列化对象MyJsonBoolean

doInBackground(Boolean.class, "{posts: [true, false]}");

protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {

    GsonBuilder gson = new GsonBuilder();
    Type collectionType = new TypeToken<MyJson<T>>(){}.getType();

    MyJson<T> myJson = gson.create().fromJson(json, collectionType);

    System.out.println(myJson.getPosts()); // [true, false]
    return myJson;
}

我假设我的例子是MyJson<T>

public class MyJson<T> {

    public List<T> posts;

    public List<T> getPosts() {
        return posts;
    }
}

因此,如果您要反序列化 a,则可以将该方法调用为List<MyObject>

// assuming no Void parameters were required
MyJson<MyObject> myJson = doInBackground(MyObject.class);

答案 2

你试过吗?

gson.create().fromJson(reader, MyJson.class);

编辑

阅读这篇文章后,似乎您使用的是正确的。我相信你的问题是使用.您必须记住,使用Java存在类型擦除。这意味着在运行时,所有实例都将替换为 。因此,在运行时,您传递GSON的内容实际上是。如果你用一个具体的类来代替它,我相信它会起作用。TypeTTObjectMyJson<Object><T>

Google Gson - 反序列化 list<class> object?(通用类型)