返回

如何解决泛型类型反序列化错误?使用自定义类型适配器

java

泛型类型的反序列化:使用自定义类型适配器

问题:未知泛型类型的反序列化

使用 Gson 传输和反序列化泛型类型的列表对象时,经常会遇到不知道如何处理泛型类型的问题。

尝试和错误

尝试直接使用List<T>() {}的类会导致错误,因为抽象方法没有实现。然后尝试使用 TypeToken 获取类型,但会抛出 NullPointerException

解决方案:自定义类型适配器

解决方法是创建一个自定义类型适配器来处理泛型类型。这个适配器需要实现 JsonDeserializerJsonSerializer 接口,用于反序列化和序列化列表对象。

public class ListTypeAdapter<T> implements JsonDeserializer<List<T>>, JsonSerializer<List<T>> {

    private final Type typeOfT;

    public ListTypeAdapter(Type typeOfT) {
        this.typeOfT = typeOfT;
    }

    @Override
    public List<T> deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
        // 从 JSON 数组中提取元素并反序列化成列表
        JsonArray jsonArray = jsonElement.getAsJsonArray();
        List<T> list = new ArrayList<>();
        for (JsonElement element : jsonArray) {
            T item = context.deserialize(element, typeOfT);
            list.add(item);
        }
        return list;
    }

    @Override
    public JsonElement serialize(List<T> src, Type typeOfSrc, JsonSerializationContext context) {
        // 将列表中的元素序列化成 JSON 数组
        JsonArray jsonArray = new JsonArray();
        for (T item : src) {
            JsonElement element = context.serialize(item, typeOfT);
            jsonArray.add(element);
        }
        return jsonArray;
    }
}

使用自定义类型适配器

通过创建 GsonBuilder 并注册自定义类型适配器,可以使用该适配器:

Type listType = new TypeToken<List<MyClass>>() {}.getType();

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(listType, new ListTypeAdapter<>(MyClass.class));
Gson gson = gsonBuilder.create();

MyClass mc = gson.fromJson(result, listType);

注意要点

  • 使用 GsonBuilder 创建 Gson 对象。
  • 确保自定义类型适配器的泛型类型与要反序列化的实际类型一致。

结论

使用自定义类型适配器可以方便地处理泛型类型的反序列化。这种方法提供了灵活性,并避免了由于不知道泛型类型而导致的错误。

常见问题解答

Q1:为什么需要创建自定义类型适配器?
A1:因为 Gson 无法自动处理泛型类型,需要一个适配器来进行反序列化。

Q2:如何使用自定义类型适配器?
A2:使用 GsonBuilder 注册类型适配器,并使用该 Gson 对象进行反序列化。

Q3:自定义类型适配器的目的是什么?
A3:将泛型类型的 JSON 表示形式反序列化为对象实例。

Q4:自定义类型适配器如何工作?
A4:它实现了 JsonDeserializer 接口来反序列化 JSON,实现了 JsonSerializer 接口来序列化对象。

Q5:何时使用自定义类型适配器?
A5:当需要反序列化具有泛型类型的对象时。