【问题标题】:Read array of anonymous class in Gson with generic class使用泛型类读取 Gson 中的匿名类数组
【发布时间】:2017-10-12 11:13:17
【问题描述】:

我使用 Gson 对 json 进行序列化和反序列化。

pojo 类:

class myData{
    public String id;
    public String name;
 }

并且通过这段代码,我得到了 pojo 类的 json。

public static Object getData(Class clazz)  {
    String json = "{'name':'john','id':'123'}";
        Gson gson = new Gson();
        return gson.fromJson(json , clazz);
}



//usage:
myData mdata= (myData) getData(myData.class);

一切都很好,在从 json 读取数组中我有这个方法:

ArrayList<myData> getDatas() {
        ArrayList<myData> mdatas = new ArrayList<>();
        String json ="[{'name':'john','code':'123'},{'name':'nick','code':'456'}]";
        Type listType = new TypeToken<ArrayList<myData>>() {
        }.getType();
        if (new Gson().fromJson(json, listType) != null) {
            return new Gson().fromJson(json, listType);
        } else {
            return mdatas;
        }
}

那个代码很好。但我想在 getDatas 中传递任何类并在 json 中找到该类,然后在结果中返回该类的列表。

类似这样的:

 ArrayList<?> getDatas(Class clazz) {
    ArrayList<clazz> mdatas = new ArrayList<>();  //this line is the problem
    String json = "[{'name':'john','code':'123'},{'name':'nick','code':'456'}]";
    //and this line
    Type listType = new TypeToken<ArrayList<clazz>>() {
    }.getType();
    if (new Gson().fromJson(json, listType) != null) {
        return new Gson().fromJson(json, listType);
    } else {
        return mdatas;
    }
}

问题是不能在arraylist 中使用匿名类。

 ArrayList<clazz> mdatas = new ArrayList<>(); 
 Type listType = new TypeToken<ArrayList<clazz>>() {

有什么方法可以将arraylist 与匿名类一起使用吗?

【问题讨论】:

  • 当您尝试您的代码时,您遇到了什么问题?
  • 是的,他们是完成它的方法,请检查:stackoverflow.com/questions/18421674/…,只需传递您的 responseString 和您的班级名称,它就会返回您的班级类型列表。
  • @vivekmahajan 的目标是创建将类作为参数传递的方法,并在 json 中找到该类的 pojo 类。

标签: java android generics arraylist gson


【解决方案1】:

如果您传递类型标记(为了编译时类型安全)或任何 Type 实例,这很容易。

使用类型标记

下面的源可以是StringReaderJsonReader 中的任何一个(请参阅fromJson 重载)。

static <E> List<E> getList(final ... source, final TypeToken<? extends List<E>> listTypeToken) {
    return gson.fromJson(source, listTypeToken.getType());
}

使用示例:

final List<MyData> list = getList(jsonReader, new TypeToken<List<MyData>>() {
});

顺便说一下,TypeTokenGson 实例是线程安全的,可以缓存到 static final 字段中。

使用没有类型标记的任何类型

static <E> List<E> getList(final ... source, final Type type) {
    return gson.fromJson(source, getParameterized(List.class, type).getType());
}

此案例使用较新的 Gson 版本创建 ParameterizedType 实例。请注意,您可以动态创建类型(不要与创建类混淆):指定参数化类型 List 并使用给定的 type 对其进行参数化。

使用示例:

final List<MyData> list = getList(jsonReader, MyData.class);

如果你不能使用最新的Gson版本,你必须像这样自己创建一个ParameterizedType实例(匿名类接口很容易理解):

static <E> List<E> getListForOlderGson(final ... source, final Type type) {
    return gson.fromJson(source, new ParameterizedType() {
        @Override
        public Type getRawType() {
            return List.class;
        }

        @Override
        public Type[] getActualTypeArguments() {
            return new Type[]{ type };
        }

        @Override
        public Type getOwnerType() {
            return null;
        }
    });
}

【讨论】:

    【解决方案2】:

    您的问题是“类”类型的实例与泛型类型不同。

    考虑以下几点:

    <T> ArrayList<T> getDatas(Class<T> clazz) {
        ArrayList<T> mdatas = new ArrayList<>();  //this line is the problem
        String json = "[{'name':'john','code':'123'},{'name':'nick','code':'456'}]";
        //and this line
        Type listType = new TypeToken<ArrayList<T>>() {
        }.getType();
        if (new Gson().fromJson(json, listType) != null) {
            return new Gson().fromJson(json, listType);
        } else {
            return mdatas;
        }
    }
    

    这会将类型作为绑定到函数的泛型类型提供,并且可以在本例中使用 clazz 参数的地方使用,从而无需将其传入。

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多