在Android开发中,JSON数据往往包含复杂数据结构,如Map
、List
等。Gson作为常用的JSON处理库,其对复杂数据结构的序列化能力至关重要。准确处理这些结构能确保数据在网络传输、本地存储等场景下保持完整的语义和结构,避免数据丢失或格式错乱。
Gson对复杂数据结构的序列化主要包含以下步骤:
:确定待序列化对象的具体类型(如HashMap
、ArrayList
)。
:根据类型从工厂链中匹配对应的TypeAdapter
。
:对于嵌套结构,递归调用序列化逻辑。
:通过JsonWriter
将数据写入字符流。
涉及的核心组件包括:
:负责具体类型的序列化操作。
:工厂链,用于创建TypeAdapter
实例。
:底层JSON字符流写入器。
:处理自定义类和复杂对象图。
Gson通过CollectionTypeAdapterFactory
处理List
等集合类型:
public final class CollectionTypeAdapterFactory implements TypeAdapterFactory { private final ConstructorConstructor constructorConstructor; public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor) { this.constructorConstructor = constructorConstructor; } @SuppressWarnings("unchecked") @Override public TypeAdapter create(Gson gson, TypeToken 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 constructor = constructorConstructor.get(typeToken); // 创建List类型适配器 return (TypeAdapter) new Adapter<>( gson, elementType, elementTypeAdapter, constructor ); } private static final class Adapter extends TypeAdapter> { private final TypeAdapter elementTypeAdapter; private final ObjectConstructor extends Collection> constructor; Adapter(Gson context, Type elementType, TypeAdapter elementTypeAdapter, ObjectConstructor extends Collection> constructor) { this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper<>( context, elementTypeAdapter, elementType ); this.constructor = constructor; } @Override public Collection read(JsonReader in) throws IOException { // 处理null值 if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } // 创建目标集合实例 Collection 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 collection) throws IOException { // 处理null值 if (collection == null) { out.nullValue(); return; } // 开始写入JSON数组 out.beginArray(); for (E element : collection) { // 递归写入每个元素 elementTypeAdapter.write(out, element); } out.endArray(); } }}
:如List
,使用PrimitiveTypeAdapter
直接写入JSON数值。
// 处理List
的写入逻辑out.beginArray();for (Integer element : list) { // 直接写入整数值 out.value(element);}out.endArray();
:如List
,递归调用User
类型的TypeAdapter
。
// 处理List
的写入逻辑out.beginArray();for (User user : list) { // 调用User类型适配器的write方法 userTypeAdapter.write(out, user);}out.endArray();
对于嵌套结构如List
,Gson会递归处理:>
外层List
适配器调用内层List
适配器。
内层List
适配器处理具体元素。
// 处理List
>的写入逻辑out.beginArray();for (List
innerList : outerList) { // 开始写入内层数组 out.beginArray(); for (Integer element : innerList) { out.value(element); } out.endArray();}out.endArray();
Gson通过MapTypeAdapterFactory
处理Map
类型:
public final class MapTypeAdapterFactory implements TypeAdapterFactory { private final ConstructorConstructor constructorConstructor; public MapTypeAdapterFactory(ConstructorConstructor constructorConstructor) { this.constructorConstructor = constructorConstructor; } @SuppressWarnings("unchecked") @Override public TypeAdapter create(Gson gson, TypeToken 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 constructor = constructorConstructor.get(typeToken); // 创建Map类型适配器 return (TypeAdapter) new Adapter<>( gson, keyType, keyAdapter, valueType, valueAdapter, constructor ); } private static final class Adapter extends TypeAdapter
:Gson要求Map的键类型必须为基本类型或String
,因为JSON的键只能是字符串。
// 处理Map
>的写入逻辑out.beginObject();for (Map.Entry > outerEntry : outerMap.entrySet()) { // 写入外层键 out.name(outerEntry.getKey()); // 开始写入内层对象 out.beginObject(); for (Map.Entry innerEntry : outerEntry.getValue().entrySet()) { out.name(innerEntry.getKey()); out.value(innerEntry.getValue()); } out.endObject();}out.endObject();
2值类型处理
:与List类似,根据值的类型递归调用相应的TypeAdapter
。
对于Map
这样的嵌套结构:
外层Map
适配器处理键值对。
内层Map
适配器处理子键值对。
// 处理Map
>的写入逻辑out.beginObject();for (Map.Entry > outerEntry : outerMap.entrySet()) { // 写入外层键 out.name(outerEntry.getKey()); // 开始写入内层对象 out.beginObject(); for (Map.Entry innerEntry : outerEntry.getValue().entrySet()) { out.name(innerEntry.getKey()); out.value(innerEntry.getValue()); } out.endObject();}out.endObject();
开发者可通过继承TypeAdapter
处理自定义复杂结构:
public class CustomListTypeAdapter extends TypeAdapter> { private final TypeAdapter elementAdapter; public CustomListTypeAdapter(TypeAdapter elementAdapter) { this.elementAdapter = elementAdapter; } @Override public List read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } List 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 list) throws IOException { if (list == null) { out.nullValue(); return; } out.beginArray(); for (T element : list) { // 自定义元素处理逻辑 if (element != null) { elementAdapter.write(out, element); } } out.endArray(); }}
通过GsonBuilder
注册:
Gson gson = new GsonBuilder() .registerTypeAdapter(List.class, new CustomListTypeAdapter<>(gson.getAdapter(Object.class))) .create();
4.3 处理特殊需求
例如,为List
添加额外元数据:
public class AnnotatedList { public int size; public List data;}public class AnnotatedListTypeAdapter extends TypeAdapter> { private final TypeAdapter> listAdapter; public AnnotatedListTypeAdapter(TypeAdapter> listAdapter) { this.listAdapter = listAdapter; } @Override public AnnotatedList read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } AnnotatedList 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 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(); }}
:自定义TypeAdapter
可避免反射开销。
:复用TypeAdapter
实例,减少创建开销。
:对大量数据采用批量写入,减少JsonWriter
操作次数。
:过深的嵌套结构会增加递归调用层数,影响性能。
:反序列化时若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);}
:处理null
值时,遵循Gson的serializeNulls
配置。
:通过JsonWriter
的对象引用跟踪机制避免无限递归。
Gson对复杂数据结构的序列化通过以下机制实现:
:CollectionTypeAdapterFactory
和MapTypeAdapterFactory
处理标准集合类型。
:通过递归调用处理嵌套结构。
:根据元素类型动态选择TypeAdapter
。
:支持自定义TypeAdapter
处理特殊结构。
:在异步场景下优化复杂结构的序列化性能。
:通过编译时生成代码减少反射开销。
:针对不同平台(如Android、JVM)提供定制化处理。
:自动处理泛型擦除带来的类型信息丢失问题。
:支持如kotlinx.collections.immutable
等新型集合库。
通过持续优化和功能扩展,Gson将继续为Android开发者提供高效、可靠的复杂数据结构处理方案。
作者:Android小码蜂链接:https://juejin.cn/post/7522090849036238899
关注我获取更多知识或者投稿