一、复杂数据结构序列化概述


1.1 复杂数据结构处理的重要性

在Android开发中,JSON数据往往包含复杂数据结构,如MapList等。Gson作为常用的JSON处理库,其对复杂数据结构的序列化能力至关重要。准确处理这些结构能确保数据在网络传输、本地存储等场景下保持完整的语义和结构,避免数据丢失或格式错乱。

1.2 核心处理流程

Gson对复杂数据结构的序列化主要包含以下步骤:

  1. 类型识别

    :确定待序列化对象的具体类型(如HashMapArrayList)。

  2. 适配器选择

    :根据类型从工厂链中匹配对应的TypeAdapter

  3. 递归处理

    :对于嵌套结构,递归调用序列化逻辑。

  4. JSON输出

    :通过JsonWriter将数据写入字符流。

1.3 关键组件

涉及的核心组件包括:

  • TypeAdapter

    :负责具体类型的序列化操作。

  • TypeAdapterFactory

    :工厂链,用于创建TypeAdapter实例。

  • JsonWriter

    :底层JSON字符流写入器。

  • 反射机制

    :处理自定义类和复杂对象图。

二、List类型的序列化原理


2.1 内置List类型适配器工厂

Gson通过CollectionTypeAdapterFactory处理List等集合类型:

public final class CollectionTypeAdapterFactory implements TypeAdapterFactory {    private final ConstructorConstructor constructorConstructor;    public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor) {        this.constructorConstructor = constructorConstructor;    }    @SuppressWarnings("unchecked")    @Override    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {        Type type = typeToken.getType();        Class<? super T> rawType = typeToken.getRawType();        // 检查是否为集合类型(如List、Set等)        if (!Collection.class.isAssignableFrom(rawType)) {            return null;        }        // 解析集合元素类型        Type elementType = $Gson$Types.getCollectionElementType(type, rawType);        TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));        // 创建集合构造器        ObjectConstructor<T> constructor = constructorConstructor.get(typeToken);        // 创建List类型适配器        return (TypeAdapter<T>) new Adapter<>(            gson, elementType, elementTypeAdapter, constructor        );    }    private static final class Adapter<E> extends TypeAdapter<Collection<E>> {        private final TypeAdapter<E> elementTypeAdapter;        private final ObjectConstructor<? extends Collection<E>> constructor;        Adapter(Gson context, Type elementType,                TypeAdapter<E> elementTypeAdapter,                ObjectConstructor<? extends Collection<E>> constructor) {            this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper<>(                context, elementTypeAdapter, elementType            );            this.constructor = constructor;        }        @Override        public Collection<E> read(JsonReader in) throws IOException {            // 处理null值            if (in.peek() == JsonToken.NULL) {                in.nextNull();                return null;            }            // 创建目标集合实例            Collection<E> collection = constructor.construct();            in.beginArray();            while (in.hasNext()) {                // 递归读取每个元素                E instance = elementTypeAdapter.read(in);                collection.add(instance);            }            in.endArray();            return collection;        }        @Override        public void write(JsonWriter out, Collection<E> collection) throws IOException {            // 处理null值            if (collection == null) {                out.nullValue();                return;            }            // 开始写入JSON数组            out.beginArray();            for (E element : collection) {                // 递归写入每个元素                elementTypeAdapter.write(out, element);            }            out.endArray();        }    }}
2.2 元素类型处理
  1. 基本类型元素

    :如List<Integer>,使用PrimitiveTypeAdapter直接写入JSON数值。

// 处理List<Integer>的写入逻辑out.beginArray();for (Integer element : list) {    // 直接写入整数值    out.value(element);}out.endArray();
  1. 对象类型元素

    :如List<User>,递归调用User类型的TypeAdapter

// 处理List<User>的写入逻辑out.beginArray();for (User user : list) {    // 调用User类型适配器的write方法    userTypeAdapter.write(out, user);}out.endArray();
2.3 嵌套List处理

对于嵌套结构如List<List<Integer>>,Gson会递归处理:

  1. 外层List适配器调用内层List适配器。

  2. 内层List适配器处理具体元素。

// 处理List<List<Integer>>的写入逻辑out.beginArray();for (List<Integer> innerList : outerList) {    // 开始写入内层数组    out.beginArray();    for (Integer element : innerList) {        out.value(element);    }    out.endArray();}out.endArray();

三、Map类型的序列化原理


3.1 内置Map类型适配器工厂

Gson通过MapTypeAdapterFactory处理Map类型:

public final class MapTypeAdapterFactory implements TypeAdapterFactory {    private final ConstructorConstructor constructorConstructor;    public MapTypeAdapterFactory(ConstructorConstructor constructorConstructor) {        this.constructorConstructor = constructorConstructor;    }    @SuppressWarnings("unchecked")    @Override    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {        Type type = typeToken.getType();        Class<? super T> rawType = typeToken.getRawType();        // 检查是否为Map类型        if (!Map.class.isAssignableFrom(rawType)) {            return null;        }        // 解析键和值的类型        Type keyType = $Gson$Types.getTypeParameter(type, Map.class, 0);        Type valueType = $Gson$Types.getTypeParameter(type, Map.class, 1);        TypeAdapter<?> keyAdapter = gson.getAdapter(TypeToken.get(keyType));        TypeAdapter<?> valueAdapter = gson.getAdapter(TypeToken.get(valueType));        // 创建Map构造器        ObjectConstructor<T> constructor = constructorConstructor.get(typeToken);        // 创建Map类型适配器        return (TypeAdapter<T>) new Adapter<>(            gson, keyType, keyAdapter, valueType, valueAdapter, constructor        );    }    private static final class Adapter<K, V> extends TypeAdapter<Map<K, V>> {        private final TypeAdapter<K> keyAdapter;        private final TypeAdapter<V> valueAdapter;        private final ObjectConstructor<? extends Map<K, V>> constructor;        Adapter(Gson context, Type keyType, TypeAdapter<K> keyAdapter,                Type valueType, TypeAdapter<V> valueAdapter,                ObjectConstructor<? extends Map<K, V>> constructor) {            this.keyAdapter = new TypeAdapterRuntimeTypeWrapper<>(                context, keyAdapter, keyType            );            this.valueAdapter = new TypeAdapterRuntimeTypeWrapper<>(                context, valueAdapter, valueType            );            this.constructor = constructor;        }        @Override        public Map<K, V> read(JsonReader in) throws IOException {            // 处理null值            if (in.peek() == JsonToken.NULL) {                in.nextNull();                return null;            }            // 创建目标Map实例            Map<K, V> map = constructor.construct();            in.beginObject();            while (in.hasNext()) {                // 读取键                K key = keyAdapter.read(in);                // 读取值                V value = valueAdapter.read(in);                map.put(key, value);            }            in.endObject();            return map;        }        @Override        public void write(JsonWriter out, Map<K, V> map) throws IOException {            // 处理null值            if (map == null) {                out.nullValue();                return;            }            // 开始写入JSON对象            out.beginObject();            for (Map.Entry<K, V> entry : map.entrySet()) {                // 写入键                keyAdapter.write(out, entry.getKey());                // 写入值                valueAdapter.write(out, entry.getValue());            }            out.endObject();        }    }}
3.2 键值对处理
  1. 键类型限制

    :Gson要求Map的键类型必须为基本类型或String,因为JSON的键只能是字符串。

// 处理Map<String, Map<String, Integer>>的写入逻辑out.beginObject();for (Map.Entry<String, Map<String, Integer>> outerEntry : outerMap.entrySet()) {    // 写入外层键    out.name(outerEntry.getKey());    // 开始写入内层对象    out.beginObject();    for (Map.Entry<String, Integer> innerEntry : outerEntry.getValue().entrySet()) {        out.name(innerEntry.getKey());        out.value(innerEntry.getValue());    }    out.endObject();}out.endObject();

2值类型处理

:与List类似,根据值的类型递归调用相应的TypeAdapter

3.3 嵌套Map处理

对于Map<String, Map<String, Integer>>这样的嵌套结构:

  1. 外层Map适配器处理键值对。

  2. 内层Map适配器处理子键值对。

// 处理Map<String, Map<String, Integer>>的写入逻辑out.beginObject();for (Map.Entry<String, Map<String, Integer>> outerEntry : outerMap.entrySet()) {    // 写入外层键    out.name(outerEntry.getKey());    // 开始写入内层对象    out.beginObject();    for (Map.Entry<String, Integer> innerEntry : outerEntry.getValue().entrySet()) {        out.name(innerEntry.getKey());        out.value(innerEntry.getValue());    }    out.endObject();}out.endObject();

四、自定义复杂数据结构的序列化


4.1 自定义TypeAdapter

开发者可通过继承TypeAdapter处理自定义复杂结构:

public class CustomListTypeAdapter<T> extends TypeAdapter<List<T>> {    private final TypeAdapter<T> elementAdapter;    public CustomListTypeAdapter(TypeAdapter<T> elementAdapter) {        this.elementAdapter = elementAdapter;    }    @Override    public List<T> read(JsonReader in) throws IOException {        if (in.peek() == JsonToken.NULL) {            in.nextNull();            return null;        }        List<T> list = new ArrayList<>();        in.beginArray();        while (in.hasNext()) {            T element = elementAdapter.read(in);            list.add(element);        }        in.endArray();        return list;    }    @Override    public void write(JsonWriter out, List<T> list) throws IOException {        if (list == null) {            out.nullValue();            return;        }        out.beginArray();        for (T element : list) {            // 自定义元素处理逻辑            if (element != null) {                elementAdapter.write(out, element);            }        }        out.endArray();    }}
4.2 注册自定义适配器

通过GsonBuilder注册:

Gson gson = new GsonBuilder()    .registerTypeAdapter(List.class, new CustomListTypeAdapter<>(gson.getAdapter(Object.class)))    .create();

4.3 处理特殊需求

例如,为List添加额外元数据:

public class AnnotatedList<T> {    public int size;    public List<T> data;}public class AnnotatedListTypeAdapter<T> extends TypeAdapter<AnnotatedList<T>> {    private final TypeAdapter<List<T>> listAdapter;    public AnnotatedListTypeAdapter(TypeAdapter<List<T>> listAdapter) {        this.listAdapter = listAdapter;    }    @Override    public AnnotatedList<T> read(JsonReader in) throws IOException {        if (in.peek() == JsonToken.NULL) {            in.nextNull();            return null;        }        AnnotatedList<T> annotatedList = new AnnotatedList<>();        in.beginObject();        while (in.hasNext()) {            String name = in.nextName();            if ("size".equals(name)) {                annotatedList.size = in.nextInt();            } else if ("data".equals(name)) {                annotatedList.data = listAdapter.read(in);            } else {                in.skipValue();            }        }        in.endObject();        return annotatedList;    }    @Override    public void write(JsonWriter out, AnnotatedList<T> value) throws IOException {        if (value == null) {            out.nullValue();            return;        }        out.beginObject();        out.name("size").value(value.size);        out.name("data");        listAdapter.write(out, value.data);        out.endObject();    }}

五、性能优化与异常处理

5.1 性能优化策略
  1. 减少反射调用

    :自定义TypeAdapter可避免反射开销。

  2. 缓存适配器

    :复用TypeAdapter实例,减少创建开销。

  3. 批量处理

    :对大量数据采用批量写入,减少JsonWriter操作次数。

  4. 避免嵌套过深

    :过深的嵌套结构会增加递归调用层数,影响性能。

5.2 异常处理机制
  1. 类型不匹配

    :反序列化时若JSON结构与Java类型不匹配,抛出

    // MapTypeAdapterFactory.Adapter的read方法try {    K key = keyAdapter.read(in);    V value = valueAdapter.read(in);    map.put(key, value);} catch (IOException e) {    throw new JsonSyntaxException("Error reading Map entry", e);}
  1. NullPointerException

    :处理null值时,遵循Gson的serializeNulls配置。

  2. 循环引用

    :通过JsonWriter的对象引用跟踪机制避免无限递归。

六、总结与展望


6.1 核心机制总结

Gson对复杂数据结构的序列化通过以下机制实现:

  • 工厂链适配

    CollectionTypeAdapterFactoryMapTypeAdapterFactory处理标准集合类型。

  • 递归处理

    :通过递归调用处理嵌套结构。

  • 类型适配

    :根据元素类型动态选择TypeAdapter

  • 扩展性

    :支持自定义TypeAdapter处理特殊结构。

6.2 未来发展方向
  1. Kotlin协程支持

    :在异步场景下优化复杂结构的序列化性能。

  2. 字节码生成

    :通过编译时生成代码减少反射开销。

  3. 多平台优化

    :针对不同平台(如Android、JVM)提供定制化处理。

  4. 更智能的类型推断

    :自动处理泛型擦除带来的类型信息丢失问题。

  5. 与新数据结构兼容

    :支持如kotlinx.collections.immutable等新型集合库。

通过持续优化和功能扩展,Gson将继续为Android开发者提供高效、可靠的复杂数据结构处理方案。

作者:Android小码蜂链接:https://juejin.cn/post/7522090849036238899

关注我获取更多知识或者投稿

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐