以前写了一篇关于如何使用GSon的文章: Json数据的解析_Gson

这里就对Gson的内部实现原理进行一个总结

创建方法

Gson可以由两种方式创建,一种是通过Gson.Builder()的方式,另一种则是通过new Gson()来创建。

那这两种创建方式有什么不同呢?

第一种Gson.Builder()的方法没有使用反射,而new Gson()是使用了反射的。

在Gson内部存在着TypeAdapter,也就是根据不同的类型来适配,党我们使用Gson.Builder()创建时,使用的是自定义的TypeAdapter而不是默认的TypeAdapter,因此也就出现了一个为反射,一个不是反射

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Gson(Excluder excluder, FieldNamingStrategy fieldNamingPolicy, Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy, List<TypeAdapterFactory> typeAdapterFactories) {
this.calls = new ThreadLocal();
this.typeTokenCache = Collections.synchronizedMap(new HashMap());
this.deserializationContext = new JsonDeserializationContext() {
public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
return Gson.this.fromJson(json, typeOfT);
}
};
this.serializationContext = new JsonSerializationContext() {
public JsonElement serialize(Object src) {
return Gson.this.toJsonTree(src);
}

public JsonElement serialize(Object src, Type typeOfSrc) {
return Gson.this.toJsonTree(src, typeOfSrc);
}
};
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
this.serializeNulls = serializeNulls;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.prettyPrinting = prettyPrinting;
ArrayList factories = new ArrayList();
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);
factories.add(excluder);
factories.addAll(typeAdapterFactories);
factories.add(TypeAdapters.STRING_FACTORY);
factories.add(TypeAdapters.INTEGER_FACTORY);
factories.add(TypeAdapters.BOOLEAN_FACTORY);
factories.add(TypeAdapters.BYTE_FACTORY);
factories.add(TypeAdapters.SHORT_FACTORY);
factories.add(TypeAdapters.newFactory(Long.TYPE, Long.class, this.longAdapter(longSerializationPolicy)));
factories.add(TypeAdapters.newFactory(Double.TYPE, Double.class, this.doubleAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.newFactory(Float.TYPE, Float.class, this.floatAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.NUMBER_FACTORY);
factories.add(TypeAdapters.CHARACTER_FACTORY);
factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
factories.add(TypeAdapters.URL_FACTORY);
factories.add(TypeAdapters.URI_FACTORY);
factories.add(TypeAdapters.UUID_FACTORY);
factories.add(TypeAdapters.LOCALE_FACTORY);
factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
factories.add(TypeAdapters.BIT_SET_FACTORY);
factories.add(DateTypeAdapter.FACTORY);
factories.add(TypeAdapters.CALENDAR_FACTORY);
factories.add(TimeTypeAdapter.FACTORY);
factories.add(SqlDateTypeAdapter.FACTORY);
factories.add(TypeAdapters.TIMESTAMP_FACTORY);
factories.add(ArrayTypeAdapter.FACTORY);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(TypeAdapters.CLASS_FACTORY);
factories.add(new CollectionTypeAdapterFactory(this.constructorConstructor));
factories.add(new MapTypeAdapterFactory(this.constructorConstructor, complexMapKeySerialization));
factories.add(new ReflectiveTypeAdapterFactory(this.constructorConstructor, fieldNamingPolicy, excluder));
this.factories = Collections.unmodifiableList(factories);
}

那Gson如何判断我们使用的是哪一种方法创建呢?其实就是通过factories这个对象 add Factory的顺序来控制的。每次获取Adapter的时候都需要遍历Factories,而我们自定义的TypeAdapter在add时是会默认添加到靠前的位置。所以这样就避免了Gson的反射解析

如何实现解析

Gson中存在一个JsonParser类,它的作用就是将json串解析成JsonElement对象。

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
public JsonElement parse(String json) throws JsonSyntaxException {
return this.parse((Reader)(new StringReader(json)));
}

public JsonElement parse(Reader json) throws JsonIOException, JsonSyntaxException {
try {
JsonReader e = new JsonReader(json);
JsonElement element = this.parse(e);
if(!element.isJsonNull() && e.peek() != JsonToken.END_DOCUMENT) {
throw new JsonSyntaxException("Did not consume the entire document.");
} else {
return element;
}
} catch (MalformedJsonException var4) {
throw new JsonSyntaxException(var4);
} catch (IOException var5) {
throw new JsonIOException(var5);
} catch (NumberFormatException var6) {
throw new JsonSyntaxException(var6);
}
}

public JsonElement parse(JsonReader json) throws JsonIOException, JsonSyntaxException {
boolean lenient = json.isLenient();
json.setLenient(true);

JsonElement e;
try {
e = Streams.parse(json);
} catch (StackOverflowError var8) {
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", var8);
} catch (OutOfMemoryError var9) {
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", var9);
} finally {
json.setLenient(lenient);
}

return e;
}

注意上面的第三个方法,里面实际上返回的是Stream.parse(json)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static JsonElement parse(JsonReader reader) throws JsonParseException {
boolean isEmpty = true;

try {
reader.peek();
isEmpty = false;
return (JsonElement)TypeAdapters.JSON_ELEMENT.read(reader);
} catch (EOFException var3) {
if(isEmpty) {
return JsonNull.INSTANCE;
} else {
throw new JsonSyntaxException(var3);
}
} catch (MalformedJsonException var4) {
throw new JsonSyntaxException(var4);
} catch (IOException var5) {
throw new JsonIOException(var5);
} catch (NumberFormatException var6) {
throw new JsonSyntaxException(var6);
}
}

这里又返回了TypeAdapters.JSON_ELEMENT.read(reader)方法,那我们就来看看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
30
31
32
33
34
35
36
37
38
39
40
public JsonElement read(JsonReader in) throws IOException {
switch(TypeAdapters.SyntheticClass_1.$SwitchMap$com$google$gson$stream$JsonToken[in.peek().ordinal()]) {
case 1:
String number = in.nextString();
return new JsonPrimitive(new LazilyParsedNumber(number));
case 2:
return new JsonPrimitive(Boolean.valueOf(in.nextBoolean()));
case 3:
return new JsonPrimitive(in.nextString());
case 4:
in.nextNull();
return JsonNull.INSTANCE;
case 5:
JsonArray array = new JsonArray();
in.beginArray();

while(in.hasNext()) {
array.add(this.read(in));
}

in.endArray();
return array;
case 6:
JsonObject object = new JsonObject();
in.beginObject();

while(in.hasNext()) {
object.add(in.nextName(), this.read(in));
}

in.endObject();
return object;
case 7:
case 8:
case 9:
case 10:
default:
throw new IllegalArgumentException();
}
}

从这上面的case我们不难看出,这里实际上就是根据不同的数据类型进行不同的数据解析。例如case 6,针对的是一个object类型,也就获取它的name和value放入object中,case 5则是针对的Array类型。

所以实际上就是解析Json,然后返回一个调用者想要的对象

一句话总结

两种创建方式,区别在于一个是反射一个不是反射。如果想要避免使用反射,自定义TypeAdapter即可,factories会自动将其添加到list的前面,当使用时就会优先遍历到指定的adapter。
JsonParser对Json串进行解析处理,根据对应的数据类型最终返回给用户一个指定的对象。这也就是我们创建一个对象实体类的原因