Gson源码分析以其所包含注解的用法

先看一张分析好的结构图:

TypeToken类:对Type类以及泛型进行了封装
官方的注解是:Represents a generic type. Java doesn’t yet provide a way to
represent generic types, so this class does.

TypeAdapter抽象类:有两个抽象方法,定义了所有类型Json的序列化和反序列的标准
abstract void write(JsonWriter out, T value)
abstract T read(JsonReader in)

TypeAdapterFactory接口:用于创建TypeAdapter

TypeAdapter create(Gson gson, TypeToken type);

Json的序列化和反序列的过程

在Gson的构造器里初始化了一系列的TypeAdapterFactory,并将其放在一个List里。 接着将Json的序列化和反序列的clazz封装成TypeToken. 遍历这个List, 根据TypeToken的类型找到相应的TypeAdapterFactory,再由工厂类创建TypeAdapter, 最后调用TypeAdapter的write和read完成Json的序列化和反序列化。

下面举两个例子进行整个过程分析:

Boolean的序列化和反序列

1
2
Gson gson = new Gson();
String json = gson.toJson(true);

上面代码是将boolean序列化,分析toJson方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public String toJson(Object src) {
if (src == null) {
return toJson(JsonNull.INSTANCE);
}
return toJson(src, src.getClass());
}

public String toJson(Object src, Type typeOfSrc) {
StringWriter writer = new StringWriter();
toJson(src, typeOfSrc, writer);
return writer.toString();
}

public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {
try {
JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
toJson(src, typeOfSrc, jsonWriter);
} catch (IOException e) {
throw new JsonIOException(e);
}
}

public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
writer.setSerializeNulls(serializeNulls);
try {
((TypeAdapter<Object>) adapter).write(writer, src);
} catch (IOException e) {
throw new JsonIOException(e);
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
}

分析上面的代码toJson(Object src)最后会调用
void toJson(Object src, Type typeOfSrc, JsonWriter writer),
JsonWriter只有一个构造函数JsonWriter(Writer),通过创建一个StringWriter实例,传到JsonWriter,stringwriter.toString()返回的String就是最终的Json

在void toJson(Object src, Type typeOfSrc, JsonWriter writer)方法里有下面这两行主要的代码:
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
((TypeAdapter) adapter).write(writer, src);

TypeToken.get(typeOfSrc)静态方法里面是new TypeToken(type),就是将
Type封装成TypeToken实例。
getAdapter方法就是寻找合适TypeAdapter的过程;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//getAdapter方法里关键代码:
for (TypeAdapterFactory factory : factories) {
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
call.setDelegate(candidate);
typeTokenCache.put(type, candidate);
return candidate;
}
}

//Gson的构造器部分代码
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
...
factories.add(TypeAdapters.BOOLEAN_FACTORY);
// 一系列TypeAdapterFactory
...
this.factories = Collections.unmodifiableList(factories);
//unmodifiableList看单词意思是无法修改的List,应该是保证这个list的添加顺序,不希望别人修改。(呵呵,第一次知道这个方法,大神们写得东西就是不一样)

遍历factories这个List 寻找TypeAdapter, 如果factory.create() 返回不为null就是满足条件的 ,感觉TypeAdapters.BOOLEAN_FACTORY就是了。
TypeAdapters.BOOLEAN_FACTORY是不是要找的呢?完成是靠第六感猜得,看看源码是不是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static final TypeAdapterFactory BOOLEAN_FACTORY
= newFactory(boolean.class, Boolean.class, BOOLEAN);

public static final TypeAdapter<Boolean> BOOLEAN = new TypeAdapter<Boolean>() {
@Override
public Boolean read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
} else if (in.peek() == JsonToken.STRING) {
// support strings for compatibility with GSON 1.7
return Boolean.parseBoolean(in.nextString());
}
return in.nextBoolean();
}
@Override
public void write(JsonWriter out, Boolean value) throws IOException {
out.value(value);
}
};

public static <TT> TypeAdapterFactory newFactory(
final Class<TT> unboxed, final Class<TT> boxed, final TypeAdapter<? super TT> typeAdapter) {
return new TypeAdapterFactory() {
@SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
return (rawType == unboxed || rawType == boxed) ? (TypeAdapter<T>) typeAdapter : null;
}
@Override public String toString() {
return "Factory[type=" + boxed.getName()
+ "+" + unboxed.getName() + ",adapter=" + typeAdapter + "]";
}
};
}

调用静态方法newFactory(boolean.class, Boolean.class, BOOLEAN),
接着调用typeToken.getRawType()获取Class对象,判断该class对象是否等于boolean.class或者Boolean.class,那么可以确定BOOLEAN就是我们要找的TypeAdapter。
这个TypeAdapter的write方法很简单,就一句out.value(value); JsonWriter的value也很简单主要就是这句:out.write(value ? “true” : “false”);
这out对象就是一开始toJson方法里的new StringWriter(),而StringWriter 实质是用StringBuffer调用append追加字符串。

看完序列化过程,相信对Boolean的反序列化过程也差不多懂了.
Boolean的反序列化代码例子如下:
Gson gson = new Gson();
boolean flag = gson.fromJson(“true”, Boolean.class);

Boolean的反序列化整个过程和序列化过程不同只是最后调用typeAdapter的read方法而已。

自定义类的序列化和反序列

自定义类的序列化

Gson gson = new Gson();
Apple apple = new Apple();
apple.name = “苹果”;
apple.price = 3;
String s = gson.toJson(apple);
//{“name”:”苹果”,”price”:3}

看完上面Boolean的序列化和反序列过程我们可以得出结论:对于不同的类的序列化和反序列化,就有相对应的的TypeAdapter,也就有相对应的TypeAdapterFactory。

在Gson的构造函数的factorys里肯定有自定义类的TypeAdapterFactory。

1
2
3
4
5
6
7
8
//Gson的构造器部分代码
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
...
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));

ReflectiveTypeAdapterFactory类应该就是了。构造函数传了4个参数:constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory
二话不说看TypeAdapterFactory接口的唯一一个方法create

1
2
3
4
5
6
7
8
9
10
@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
Class<? super T> raw = type.getRawType();

if (!Object.class.isAssignableFrom(raw)) { // raw必须继承Object,否则返回null
return null; // it's a primitive!
}

ObjectConstructor<T> constructor = constructorConstructor.get(type);
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}

ConstructorConstructor类: Constructor是构造器的意思,构造器的构造器,这一个类的作用是根据Type生成相应构造器实例。
ObjectConstructor constructor = constructorConstructor.get(type);这行代码的construtor是根据传入type返回的构造器的实例。
getBoundFields(gson, type, raw)这个方法返回一个Map, 存储了这个Type的所有Field的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//ConstructorConstructor里的部分源码

private final Map<Type, InstanceCreator<?>> instanceCreators;

public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
final Type type = typeToken.getType();
final Class<? super T> rawType = typeToken.getRawType();

// first try an instance creator

@SuppressWarnings("unchecked") // types must agree
final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
if (typeCreator != null) {
return new ObjectConstructor<T>() {
@Override public T construct() {
return typeCreator.createInstance(type);
}
};
}

// Next try raw type match for instance creators
@SuppressWarnings("unchecked") // types must agree
final InstanceCreator<T> rawTypeCreator =
(InstanceCreator<T>) instanceCreators.get(rawType);
if (rawTypeCreator != null) {
return new ObjectConstructor<T>() {
@Override public T construct() {
return rawTypeCreator.createInstance(type);
}
};
}

ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
if (defaultConstructor != null) {
return defaultConstructor;
}

ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
if (defaultImplementation != null) {
return defaultImplementation;
}

// finally try unsafe
return newUnsafeAllocator(type, rawType);
}

InstanceCreator是个接口,只有T createInstance(Type type)方法。

ConstructorConstructor类instanceCreators是一个Map>,从Gson的构造函数中传来的,给使用者自定义类生成构造器实例用的。
在ObjectConstructor get(TypeToken typeToken)这个方法里,先在instanceCreators里寻找有没有合适的InstanceCreator,如果没有接着
调用newDefaultConstructor(rawType),还没接着调用newDefaultImplementationConstructor(type, rawType),最后还没有调用newUnsafeAllocator(type, rawType)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

​```sh
//看下getBoundFields方法的实现。

private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
if (raw.isInterface()) {
return result;// 如果是接口,直接返回空的LinkedHashMap
}

Type declaredType = type.getType();
while (raw != Object.class) {
Field[] fields = raw.getDeclaredFields();
for (Field field : fields) {
boolean serialize = excludeField(field, true);
boolean deserialize = excludeField(field, false);
if (!serialize && !deserialize) {
continue;
}
field.setAccessible(true);
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
List<String> fieldNames = getFieldNames(field);
BoundField previous = null;
for (int i = 0; i < fieldNames.size(); ++i) {
String name = fieldNames.get(i);
if (i != 0) serialize = false; // only serialize the default name
BoundField boundField = createBoundField(context, field, name,
TypeToken.get(fieldType), serialize, deserialize);
BoundField replaced = result.put(name, boundField);
if (previous == null) previous = replaced;
}
if (previous != null) {
throw new IllegalArgumentException(declaredType
+ " declares multiple JSON fields named " + previous.name);
}
}
type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
raw = type.getRawType();
}
return result;
}

从当前类的Type到当前类的最顶层父类把所有的Field遍历完,直到最顶层类为Object停止。
先会调用excludeField(Class field, boolean serialize)方法两次,分别判断是否跳过当前Field的序列化和反序列化。
List fieldNames = getFieldNames(field)收集当前Field的有关的所有fieldName, 如果当前Field没有SerializedName注解,
就只有一个fieldName。如果用SerializedName注解就可能有多个fileName。遍历fieldNames的List,生成BoundField。最后就
可以得到一个LinkedHashMap(),存储了这个Type的所有Field的信息。

SerializedName注解的用法
1
2
3
4
5
6
7
8
9
10
public @interface SerializedName {

/**
* @return the desired name of the field when it is serialized or deserialized
*/
String value();
/**
* @return the alternative names of the field when it is deserialized
*/
String[] alternate() default {};

SerializedName注解里第一个值是String,可以用序列化,也可以用于反序列化。
第二个值只用于反序列化。举个例子怎么用:

1
2
3
4
5
6
7
8
public class Apple{
@SerializedName(value = "name1", alternate = {"name2", "name3"})
String name;
int price;
}
// Apple序列化为:{"name1":"苹果","price":3} 序列化认注解里value的值
// 注解里alternate的值是String[], 反序列化时Json的key 只要能和value或者alternate数组里能匹配就能反序列化
// {"name3":"苹果","price":3} 也是可以反序列化的

收集当前类的Field信息前掉调用excludeField(Class field, boolean serialize)方法两次,分别判断是否跳过当前Field的序列化和反序列化。

1
2
3
4
5
6
7
8
9

​```sh
public boolean excludeField(Field f, boolean serialize) {
return excludeField(f, serialize, excluder);
}

static boolean excludeField(Field f, boolean serialize, Excluder excluder) {
return !excluder.excludeClass(f.getType(), serialize) && !excluder.excludeField(f, serialize);
}

从上面代码可以看出来最后会调用Excluder的excludeClass(Class<?> clazz, boolean serialize) 和 excludeField(Field field, boolean serialize)
分别对当前Field的所属的class以及Field本身实行两层过滤Field。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public boolean excludeClass(Class<?> clazz, boolean serialize) {
if (version != Excluder.IGNORE_VERSIONS
&& !isValidVersion(clazz.getAnnotation(Since.class), clazz.getAnnotation(Until.class))) {
return true;
}

if (!serializeInnerClasses && isInnerClass(clazz)) {
return true;
}

if (isAnonymousOrLocal(clazz)) {
return true;
}

List<ExclusionStrategy> list = serialize ? serializationStrategies : deserializationStrategies;
for (ExclusionStrategy exclusionStrategy : list) {
if (exclusionStrategy.shouldSkipClass(clazz)) {
return true;
}
}

return false;
}

这里涉及到@Since和@Util这两个有关版本号的注解,默认是忽略版本,如果有设置版本号,规则是当前版本号满足@Since >= version >= @Util,否则跳过这个字段。
接着是否不序列化内部类,serializeInnerClasses这个boolean默认是true,也就说默认是序列化内部类的, 但序列化的内部类要是静态的,
isAnonymousOrLocal()方法,用来检测是否是匿名内部类,
最后一层过滤是List,遍历这个list, 如果shouldSkipClass(clazz)返回true就会跳过当前 。ExclusionStrategy是一个接口,是由调用者自定义是实现过滤的规则。serializationStrategies和deserializationStrategies
分别用来序列化和反序列化过滤的,当使用GsonBuilder的addSerializationExclusionStrategy(ExclusionStrategy strategy)和addDeserializationExclusionStrategy(ExclusionStrategy strategy)
两个方法就可以实现自定义过滤规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public boolean excludeField(Field field, boolean serialize) {
if ((modifiers & field.getModifiers()) != 0) {
return true;
}

if (version != Excluder.IGNORE_VERSIONS
&& !isValidVersion(field.getAnnotation(Since.class), field.getAnnotation(Until.class))) {
return true;
}

if (field.isSynthetic()) {
return true;
}

if (requireExpose) {
Expose annotation = field.getAnnotation(Expose.class);
if (annotation == null || (serialize ? !annotation.serialize() : !annotation.deserialize())) {
return true;
}
}

if (!serializeInnerClasses && isInnerClass(field.getType())) {
return true;
}

if (isAnonymousOrLocal(field.getType())) {
return true;
}

List<ExclusionStrategy> list = serialize ? serializationStrategies : deserializationStrategies;
if (!list.isEmpty()) {
FieldAttributes fieldAttributes = new FieldAttributes(field);
for (ExclusionStrategy exclusionStrategy : list) {
if (exclusionStrategy.shouldSkipField(fieldAttributes)) {
return true;
}
}
}

return false;
}

这个excludeField方法跟上面分析excludeClass差不多,也会根据@Since和@Util这两个有关版本号的注解过滤,遍历List, shouldSkipField()方法返回true是过滤掉。
但当前field的修饰符是 Modifier.TRANSIENT 或 Modifier.STATIC 不会序列化和反序列化。
这里有一个Expose的注解,从上面的源码看,要使用这个注解requireExpose必须为true, 但是requireExpose默认是false。也就是说默认情况下在字段上使用这个注解没有任何意义.
只用使用GsonBuilder的excludeFieldsWithoutExposeAnnotation()后才有效, 开启后你的class里字段必须要有Expose注解才会被序列化和反序列化。
下面举个例子说明怎么使用Expose的注解

Expose的注解使用

这个注解由两个boolean值,默认都是true:@Expose(serialize=true, deserialize = true)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Apple {
@Expose
String name;
@Expose(serialize=false, deserialize = true)
int price;

String breed;

@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
", price=" + price +
", breed='" + breed + '\'' +
'}';
}
}

//test
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Apple apple = new Apple();
apple.name = "苹果";
apple.price = 3;
apple.breed = "高品质";
String s = gson.toJson(apple);
String json = "{\"name\":\"苹果\",\"price\":3,\"breed\":\"高品质\"}";
Apple apple1 = gson.fromJson(json, Apple.class);
System.out.println(apple1);


//最终结果:{"name":"苹果"} Apple{name='苹果', price=3, breed='null'}
//
//调用excludeFieldsWithoutExposeAnnotation()后, Apple的属性必须加Expose注解才会被序列化或者反序列化,
//也可以用Expose注解里的serialize和deserialize分别设置当前属性是否序列化或反序列化
ExclusionStrategy的用法

自定义ExclusionStrategy接口实现过滤序列化的自定义注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SkipSerializeField {
}

public static class Pear{
String name;
int price;
@SkipSerializeField
String breed;
}

private class MySerializationExclusionStrategy implements ExclusionStrategy{

@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(SkipSerializeField.class) != null;
}

@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}

@Test
public void test2(){
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(new MySerializationExclusionStrategy())
.create();
Pear pear = new Pear();
pear.name = "雪梨";
pear.price = 3;
pear.breed = "高品质";
String s = gson.toJson(pear);
System.out.println(s); //{"name":"雪梨","price":3} 过滤了Pear的breed属性
}

前面收集好所有需要序列化的信息,最后就是序列化的过程里,也就TypeAdapter的write方法的调用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//new Adapter<T>(constructor, getBoundFields(gson, type, raw))
// 这个Adapter<T>类,是ReflectiveTypeAdapterFactory的内部类;
// 先只看序列化部分,也就是write方法:
@Override public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue(); // 处理value为null的情况
return;
}

out.beginObject(); // 开始
try {
for (BoundField boundField : boundFields.values()) {
if (boundField.writeField(value)) {
out.name(boundField.name);
boundField.write(out, value);
}
}
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
out.endObject(); // 结束
}

out.name(boundField.name) 这方法应该记录json的key, boundField.write(out, value) 这个方法就是json的value部分。
看看BoundField的write方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//createBoundField方法在遍历Class的所有Fields时就调用,生成BoundField
private ReflectiveTypeAdapterFactory.BoundField createBoundField(
final Gson context, final Field field, final String name,
final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
// special casing primitives here saves ~5% on Android...
JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
TypeAdapter<?> mapped = null;
if (annotation != null) {
mapped = jsonAdapterFactory.getTypeAdapter(
constructorConstructor, context, fieldType, annotation);
}
final boolean jsonAdapterPresent = mapped != null;
if (mapped == null) mapped = context.getAdapter(fieldType);

final TypeAdapter<?> typeAdapter = mapped;
return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
@SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
@Override void write(JsonWriter writer, Object value)
throws IOException, IllegalAccessException {
Object fieldValue = field.get(value);
TypeAdapter t = jsonAdapterPresent ? typeAdapter
: new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
t.write(writer, fieldValue);
}
@Override void read(JsonReader reader, Object value)
throws IOException, IllegalAccessException {
Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
field.set(value, fieldValue);
}
}
@Override public boolean writeField(Object value) throws IOException, IllegalAccessException {
if (!serialized) return false;
Object fieldValue = field.get(value);
return fieldValue != value; // avoid recursion for example for Throwable.cause
}
};
}

每一次return是一个ReflectiveTypeAdapterFactory.BoundField的匿名内部类,实现了write和read方法。
序列化时由反射类型的TypeAdapter的write委托给BoundField的write方法, BoundField的write方法里有一句关键的代码:
TypeAdapter t = jsonAdapterPresent ? typeAdapter : new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
这句代码说白了还是根据field的类型去寻找合适的TypeAdapter,
默认情况下jsonAdapterPresent时false, 也t = new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
当field上加了JsonAdapter注解时,jsonAdapterPresent就为true, JsonAdapter注解给我们提供了自定义TypeAdapter的实现

JsonAdapter注解的用法

JsonAdapter注解的value必须是TypeAdapter或者TypeAdapterFactory类,
不管是自定义TypeAdapterFactory还是TypeAdapter, 目的都是为了实现自定义的序列化和反序列化,主要也是重写write和read的方法

继续分析默认没使用JsonAdapter注解的情况,看看new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType())实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//TypeAdapterRuntimeTypeWrapper类,自身继承TypeAdapter, 构造函数又传了一个具体的TypeAdapter.
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void write(JsonWriter out, T value) throws IOException {
// Order of preference for choosing type adapters
// First preference: a type adapter registered for the runtime type
// Second preference: a type adapter registered for the declared type
// Third preference: reflective type adapter for the runtime type (if it is a sub class of the declared type)
// Fourth preference: reflective type adapter for the declared type

TypeAdapter chosen = delegate;
Type runtimeType = getRuntimeTypeIfMoreSpecific(type, value);
if (runtimeType != type) {
TypeAdapter runtimeTypeAdapter = context.getAdapter(TypeToken.get(runtimeType));
if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
// The user registered a type adapter for the runtime type, so we will use that
chosen = runtimeTypeAdapter;
} else if (!(delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {
// The user registered a type adapter for Base class, so we prefer it over the
// reflective type adapter for the runtime type
chosen = delegate;
} else {
// Use the type adapter for runtime type
chosen = runtimeTypeAdapter;
}
}
chosen.write(out, value);
}

/**
* Finds a compatible runtime type if it is more specific
*/
private Type getRuntimeTypeIfMoreSpecific(Type type, Object value) {
if (value != null
&& (type == Object.class || type instanceof TypeVariable<?> || type instanceof Class<?>)) {
type = value.getClass();
}
return type;
}

write方法里根据Field的Type和运行时Type比较,找出真正的TypeAdapter。
好抽象,还是举个栗子把:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class C{
private int i;
}

public class C1 extend C{
private String j;
}

public class A{
private C c;
}

//test
A a = new A();
a.c = new C1();
new Gson().toJson(a);

A是将要序列化的类,A 有个成员变量C,但a.c真正赋值时可以时C1.

在这种情况下看回TypeAdapterRuntimeTypeWrapper的write方法,runtimeType就C1,而当前type是C,这时runtimeTypeAdapter当点真正TypeAdapter,
如果不做这种判断,那么序列化时只有C1继承C的属性才序列化,C1扩展的属性并没有序列化。
TypeAdapterRuntimeTypeWrapper的委托delegate如果是ReflectiveTypeAdapterFactory.Adapter类型,又会递归再一次调用TypeAdapterRuntimeTypeWrapper的write方法,
直到时StringTypeAdapter, BooleanTypeAdapter等基本类型TypeAdapter, 组装成String。

自定义类的反序列化

反序列化和序列化不同地方是调用TypeAdater的read方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//new Adapter<T>(constructor, getBoundFields(gson, type, raw))
// 这个Adapter<T>类,是ReflectiveTypeAdapterFactory的内部类;
@Override public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}

T instance = constructor.construct();

try {
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
BoundField field = boundFields.get(name);
if (field == null || !field.deserialized) {
in.skipValue();
} else {
field.read(in, instance);
}
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
in.endObject();
return instance;
}

创建实例instance, 循环根据json的key,在boundFields这个Map拿出对应BoundField,调用boundField的read()

1
2
3
4
5
6
7
@Override void read(JsonReader reader, Object value)
throws IOException, IllegalAccessException {
Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
field.set(value, fieldValue);
}
}

反序化会比序列化简单点。序列化需要判断runtimeType和Type对比,找出真正的TypeAdapter。
为什么?因为,比如说A是反序列化的类,A 有个成员变量C,如果你直接想反序列时创建C1(继承C)赋值为C,这是不可能的,
因为反序列时无法获取C1的class对象。如果真有这种需求可以使用JsonAdapter注解实现自定义TypeAdapter。

Loading comments box needs to over the wall