码字不易,请大佬们点点关注,谢谢~
一、复杂数据结构序列化概述
1.1 复杂数据结构处理的重要性
在Android开发中,JSON数据往往包含复杂数据结构,如Map、List等。Gson作为常用的JSON处理库,其对复杂数据结构的序列化能力至关重要。准确处理这些结构能确保数据在网络传输、本地存储等场景下保持完整的语义和结构,避免数据丢失或格式错乱。
1.2 核心处理流程
Gson对复杂数据结构的序列化主要包含以下步骤:
- 类型识别:确定待序列化对象的具体类型(如
HashMap、ArrayList)。 - 适配器选择:根据类型从工厂链中匹配对应的
TypeAdapter。 - 递归处理:对于嵌套结构,递归调用序列化逻辑。
- 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 元素类型处理
- 基本类型元素:如
List<Integer>,使用PrimitiveTypeAdapter直接写入JSON数值。
// 处理List<Integer>的写入逻辑
out.beginArray();
for (Integer element : list) {
// 直接写入整数值
out.value(element);
}
out.endArray();
- 对象类型元素:如
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会递归处理:
- 外层
List适配器调用内层List适配器。 - 内层
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 键值对处理
- 键类型限制:Gson要求Map的键类型必须为基本类型或
String,因为JSON的键只能是字符串。
// 写入键值对逻辑
for (Map.Entry<K, V> entry : map.entrySet()) {
// 将键转换为字符串(如果需要)
keyAdapter.write(out, entry.getKey());
valueAdapter.write(out, entry.getValue());
}
- 值类型处理:与List类似,根据值的类型递归调用相应的
TypeAdapter。
3.3 嵌套Map处理
对于Map<String, Map<String, Integer>>这样的嵌套结构:
- 外层
Map适配器处理键值对。 - 内层
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 性能优化策略
- 减少反射调用:自定义
TypeAdapter可避免反射开销。 - 缓存适配器:复用
TypeAdapter实例,减少创建开销。 - 批量处理:对大量数据采用批量写入,减少
JsonWriter操作次数。 - 避免嵌套过深:过深的嵌套结构会增加递归调用层数,影响性能。
5.2 异常处理机制
- 类型不匹配:反序列化时若JSON结构与Java类型不匹配,抛出
JsonSyntaxException。
// 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);
}
- NullPointerException:处理
null值时,遵循Gson的serializeNulls配置。 - 循环引用:通过
JsonWriter的对象引用跟踪机制避免无限递归。
六、总结与展望
6.1 核心机制总结
Gson对复杂数据结构的序列化通过以下机制实现:
- 工厂链适配:
CollectionTypeAdapterFactory和MapTypeAdapterFactory处理标准集合类型。 - 递归处理:通过递归调用处理嵌套结构。
- 类型适配:根据元素类型动态选择
TypeAdapter。 - 扩展性:支持自定义
TypeAdapter处理特殊结构。
6.2 未来发展方向
- Kotlin协程支持:在异步场景下优化复杂结构的序列化性能。
- 字节码生成:通过编译时生成代码减少反射开销。
- 多平台优化:针对不同平台(如Android、JVM)提供定制化处理。
- 更智能的类型推断:自动处理泛型擦除带来的类型信息丢失问题。
- 与新数据结构兼容:支持如
kotlinx.collections.immutable等新型集合库。
通过持续优化和功能扩展,Gson将继续为Android开发者提供高效、可靠的复杂数据结构处理方案。