Java GSON将序列化/反序列化到自定义泛型集合类型或从自定义泛型集合类型进行序列化/反序列化

Java GSON将序列化/反序列化到自定义泛型集合类型或从自定义泛型集合类型进行序列化/反序列化,java,json,libgdx,gson,deserialization,Java,Json,Libgdx,Gson,Deserialization,我正在寻找一种方法来配置GSON,以便序列化到自定义泛型集合类型并从中反序列化 正在讨论的集合是类型 我无法找到如何实现这一点的文档。有人能帮忙吗?解决方案1: 转换为标准Java数组。由于数组实际上只是标准Java数组的包装器,所以在转换它时不会丢失数据,Gson可以轻松地为我们处理标准数组的序列化和反序列化 Array<Human> array = new Array<Human>(); array.add(new Human("Jack")); array.add(

我正在寻找一种方法来配置GSON,以便序列化到自定义泛型集合类型并从中反序列化

正在讨论的集合是类型


我无法找到如何实现这一点的文档。有人能帮忙吗?

解决方案1:

转换为标准Java数组。由于数组实际上只是标准Java数组的包装器,所以在转换它时不会丢失数据,Gson可以轻松地为我们处理标准数组的序列化和反序列化

Array<Human> array = new Array<Human>();
array.add(new Human("Jack"));
array.add(new Human("Tom"));
array.add(new Human("Mel"));
array.add(new Human("Anne"));

Gdx.app.log("JSON", "To json");
for (Human human : array) {
    Gdx.app.log("Human", human.name);
}

Gson gson = new Gson();
String json = gson.toJson(array.toArray(), Human[].class);
Array<Human> arrayFromJson = new Array<Human>(gson.fromJson(json, Human[].class));

Gdx.app.log("JSON", "From json");
for (Human human : arrayFromJson) {
    Gdx.app.log("Human", human.name);
}
解决方案2:

如果在某种对象中有
Array
,则需要手动将Java数组转换为LibGDX数组,这会有点混乱

编写自己的序列化程序是解决这个问题的方法,但使用泛型编写序列化程序是复杂的,但也是可能的

最难的部分是反序列化程序:

public class ArrayDeserializer<T> implements JsonDeserializer<Array<T>> {
    Class<T[]> tClass;

    public ArrayDeserializer(Class<T[]> tClass) {
        this.tClass = tClass;
    }

    @Override
    public Array<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        T[] objects = context.deserialize(json, tClass);
        return new Array<T>(objects);
    }
}
公共类ArrayDeserializer实现JsonDeserializer{
类tClass;
公共ArraydSerializer(类tClass){
this.tClass=tClass;
}
@凌驾
公共数组反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
T[]objects=context.deserialize(json,tClass);
返回新数组(对象);
}
}
序列化程序非常愚蠢

public class ArraySerializer implements JsonSerializer<Array> {
    @Override
    public JsonElement serialize(Array src, Type typeOfSrc, JsonSerializationContext context) {
        return context.serialize(src.toArray(), src.toArray().getClass());
    }
}
公共类ArraySerializer实现JsonSerializer{
@凌驾
公共JsonElement序列化(数组src,类型typeOfSrc,JsonSerializationContext){
返回context.serialize(src.toArray(),src.toArray().getClass());
}
}
然后在代码中使用:

Type type = TypeToken.get(array.getClass()).getType(); //Array<Human>
...
gsonBuilder.registerTypeAdapter(type, new ArrayDeserializer<Human>(Human[].class));
gsonBuilder.registerTypeAdapter(type, new ArraySerializer());
Type Type=TypeToken.get(array.getClass()).getType()//排列
...
registerTypeAdapter(类型,新的ArraydSerializer(Human[].class));
registerTypeAdapter(类型,new ArraySerializer());

然后构建能够序列化libGDX数组的新Gson实例。

解决方案1:

转换为标准Java数组。由于数组实际上只是标准Java数组的包装器,所以在转换它时不会丢失数据,Gson可以轻松地为我们处理标准数组的序列化和反序列化

Array<Human> array = new Array<Human>();
array.add(new Human("Jack"));
array.add(new Human("Tom"));
array.add(new Human("Mel"));
array.add(new Human("Anne"));

Gdx.app.log("JSON", "To json");
for (Human human : array) {
    Gdx.app.log("Human", human.name);
}

Gson gson = new Gson();
String json = gson.toJson(array.toArray(), Human[].class);
Array<Human> arrayFromJson = new Array<Human>(gson.fromJson(json, Human[].class));

Gdx.app.log("JSON", "From json");
for (Human human : arrayFromJson) {
    Gdx.app.log("Human", human.name);
}
解决方案2:

如果在某种对象中有
Array
,则需要手动将Java数组转换为LibGDX数组,这会有点混乱

编写自己的序列化程序是解决这个问题的方法,但使用泛型编写序列化程序是复杂的,但也是可能的

最难的部分是反序列化程序:

public class ArrayDeserializer<T> implements JsonDeserializer<Array<T>> {
    Class<T[]> tClass;

    public ArrayDeserializer(Class<T[]> tClass) {
        this.tClass = tClass;
    }

    @Override
    public Array<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        T[] objects = context.deserialize(json, tClass);
        return new Array<T>(objects);
    }
}
公共类ArrayDeserializer实现JsonDeserializer{
类tClass;
公共ArraydSerializer(类tClass){
this.tClass=tClass;
}
@凌驾
公共数组反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
T[]objects=context.deserialize(json,tClass);
返回新数组(对象);
}
}
序列化程序非常愚蠢

public class ArraySerializer implements JsonSerializer<Array> {
    @Override
    public JsonElement serialize(Array src, Type typeOfSrc, JsonSerializationContext context) {
        return context.serialize(src.toArray(), src.toArray().getClass());
    }
}
公共类ArraySerializer实现JsonSerializer{
@凌驾
公共JsonElement序列化(数组src,类型typeOfSrc,JsonSerializationContext){
返回context.serialize(src.toArray(),src.toArray().getClass());
}
}
然后在代码中使用:

Type type = TypeToken.get(array.getClass()).getType(); //Array<Human>
...
gsonBuilder.registerTypeAdapter(type, new ArrayDeserializer<Human>(Human[].class));
gsonBuilder.registerTypeAdapter(type, new ArraySerializer());
Type Type=TypeToken.get(array.getClass()).getType()//排列
...
registerTypeAdapter(类型,新的ArraydSerializer(Human[].class));
registerTypeAdapter(类型,new ArraySerializer());

然后构建能够序列化libGDX数组的新Gson实例。

是否可以以通用方式添加ArraydSerializer,这样我就不需要为每个要序列化的数组实例化一个实例?是否可以以通用方式添加ArraydSerializer,这样我就不需要为每个要序列化的数组实例化它的一个实例了?