以前一段時間,準備把糗百的項目中json解析的模塊中的原生Json解析換成gson解析,工做比較繁雜,坑多,所以爲了防止出錯,我還對Gson作了一個源碼分析。這一篇就是Gson源碼分析的總結,同時對Gson內部運用的設計模式也進行了總結,相信瞭解了它的源碼和運行機制,對於使用Gson的使用會更有幫助。html
Gson,就是幫助咱們完成序列化和反序列化的工做的一個庫。json
UserInfo userInfo = getUserInfo();
Gson gson = new Gson();
String jsonStr = gson.toJson(userInfo); // 序列化
UserInfo user = gson.fromJson(jsonStr,UserInfo.class); // 反序列化
複製代碼
實際上咱們用的最多的是Gson的反序列化,主要在解析服務器返回的json串。所以,後面的文章也會以Gson中的反序列化的過程爲主來分析代碼。設計模式
在分析以前,咱們先作個簡單的猜測,要如何實現反序列化的流程的,Gson大致會作一下這三件事:緩存
事實上,Gson想要把json數據反序列化基本都逃不掉這三個步驟,可是這三個步驟就像小品裏分三步把大象裝進冰箱同樣。咱們知道最複雜的一步就是把大象裝進去,畢竟,開冰箱門或者關冰箱門你們都會的嘛。在Gson中,複雜的就是怎樣把json中對應數據放入對應的屬性中。而這個問題的答案就是Gson的TypeAdapter。bash
TypeAdapter是Gson的核心,它的意思是類型適配器,而說到適配器,你們都會想到適配器模式,沒錯,這個TypeAdapter的設計這確實是一個適配器模式,由於Json數據接口和Type的接口二者是沒法兼容,所以TypeAdapter就是來實現兼容,把json數據讀到Type中,把Type中的數據寫入到Json裏。服務器
public abstract class TypeAdapter<T> {
// JsonWriter表明Json數據,T則是對應的Type的對象
public abstract void write(JsonWriter out, T value) throws IOException;
// JsonWriter表明Json數據,T則是對應的Type的對象
public abstract T read(JsonReader in) throws IOException;
...
...
...
}
複製代碼
簡單而言,TypeAdapter的做用就是針對Type進行適配,保證把json數據讀到Type中,或者把Type中的數據寫入到Json裏數據結構
Gson會爲每一種類型建立一個TypeAdapter,一樣的,每個Type都對應惟一一個TypeAdapter多線程
而全部Type(類型),在Gson中又能夠分爲基本類型和複合類型(非基本類型)app
這裏的基本類型和複合類型(非基本類型)是筆者定義的詞彙,由於這樣定義對於讀者理解Gson源碼和運行機制更有幫助。ide
如上圖,每一種基本類型都會建立一個TypeAdapter來適配它們,而全部的複合類型(即咱們本身定義的各類JavaBean)都會由ReflectiveTypeAdapter來完成適配
既然講到了每種Type都有對應的TypeAdapter,那麼爲何說TypeAdapter是Gson的核心呢?咱們能夠看看Gson究竟是如何實現Json解析的呢,下圖是Gson完成json解析的抽象簡化的流程圖:
如上圖,若是是基本類型,那麼對應的TypeAdapter就能夠直接讀寫Json串,若是是複合類型,ReflectiveTypeAdapter會反射建立該類型的對象,並逐個分析其內部的屬性的類型,而後重複上述工做。直至全部的屬性都是Gson認定的基本類型並完成讀寫工做。
當類型是複合類型的時候,Gson會建立ReflectiveTypeAdapter,咱們能夠看看這個Adapter的源碼:
// 建立ReflectiveTypeAdapter
new Adapter<T>(constructor, getBoundFields(gson, type, raw));
...
...
/**
* ReflectiveTypeAdapter是ReflectiveTypeAdapterFactory的內部類,其實際的類名就是Adapter
* 本文只是爲了區別其餘的TypeAdapter而叫它 ReflectiveTypeAdapter
**/
public static final class Adapter<T> extends TypeAdapter<T> {
// 該複合類型的構造器,用於反射建立對象
private final ObjectConstructor<T> constructor;
// 該類型內部的全部的Filed屬性,都經過map存儲起來
private final Map<String, BoundField> boundFields;
Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) {
this.constructor = constructor;
this.boundFields = boundFields;
}
//JsonReader是Gson封裝的對Json相關的操做類,能夠依次讀取json數據
// 相似的能夠參考Android封裝的對XML數據解析的操做類XmlPullParser
@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(); //開始逐個讀取json串中的key
BoundField field = boundFields.get(name); // 經過key尋找對應的屬性
if (field == null || !field.deserialized) {
in.skipValue();
} else {
field.read(in, instance); // 將json串的讀取委託給了各個屬性
}
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
in.endObject(); // 到對應的「}」結束
return instance;
}
...
...
}
複製代碼
Gson內部並無ReflectiveTypeAdapter這個類,它其其實是ReflectiveTypeAdapterFactory類一個名叫Adapter的內部類,叫它ReflectiveTypeAdapter是爲了表意明確。
咱們看到,ReflectiveTypeAdapter內部會首先建立該類型的對象,而後遍歷該對象內部的全部屬性,接着把json傳的讀去委託給了各個屬性。
被委託的BoundField內部又是如何作的呢?BoundField這個類,是對Filed相關操做的封裝,咱們來看看BoundField是如何建立的,以及內部的工做原理。
// 建立ReflectiveTypeAdapter getBoundFields獲取該類型全部的屬性
new Adapter<T>(constructor, getBoundFields(gson, type, raw));
...
...
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
// 建立一個Map結構,存放全部的BoundField
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
if (raw.isInterface()) {
return result;
}
Type declaredType = type.getType();
while (raw != Object.class) { // 若是類型是Object則結束循環
Field[] fields = raw.getDeclaredFields(); // 獲取該類型的全部的內部屬性
for (Field field : fields) {
boolean serialize = excludeField(field, true);
boolean deserialize = excludeField(field, false);
if (!serialize && !deserialize) {
continue;
}
accessor.makeAccessible(field);
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
List<String> fieldNames = getFieldNames(field); // 獲取該Filed的名字(Gson經過註解能夠給一個屬性多個解析名)
BoundField previous = null;
for (int i = 0, size = fieldNames.size(); i < size; ++i) {
String name = fieldNames.get(i);
// 多個解析名,第一做爲默認的序列化名稱
if (i != 0) serialize = false; // only serialize the default name
// 建立BoundField
BoundField boundField = createBoundField(context, field, name,
TypeToken.get(fieldType), serialize, deserialize);
// 將BoundField放入Map中,獲取被替換掉的value(若是有的話)
BoundField replaced = result.put(name, boundField);
// 作好記錄
if (previous == null) previous = replaced;
}
if (previous != null) {
// 若是previous != null證實出現了兩個相同的Filed name,直接拋出錯誤
// 注:Gson不容許定義兩個相同的名稱的屬性(父類和子類之間可能出現)
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(); // 獲取父類類型,最終會索引到Object.由於Object是全部對象的父類
}
return result;
}
複製代碼
上面這段代碼的主要工做就是,找到該類型內部的全部屬性,並嘗試逐一封裝成BoundField。
// 根據每一個Filed建立BoundField(封裝Filed讀寫操做)
private ReflectiveTypeAdapterFactory.BoundField createBoundField(
final Gson context, final Field field, final String name,
final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
// 是不是原始數據類型 (int,boolean,float...)
final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
...
...
if (mapped == null){
// Gson嘗試獲取該類型的TypeAdapter,這個方法咱們後面也會繼續提到。
mapped = context.getAdapter(fieldType);
}
// final變量,便於內部類使用
final TypeAdapter<?> typeAdapter = mapped;
return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
...
...
// ReflectiveTypeAdapter委託的Json讀操做會調用到這裏
@Override void read(JsonReader reader, Object value)
throws IOException, IllegalAccessException {
// 經過該屬性的類型對應的TypeAdapter嘗試讀取json串
//若是是基礎類型,則直接讀取,
//若是是複合類型則遞歸以前的流程
Object fieldValue = typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive) {
field.set(value, fieldValue); //更新filed值
}
}
@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
}
};
}
複製代碼
假設該複合類型中全部的屬性的類型是String,則屬性所對應的TypeAdapter以及其讀寫方式以下:
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
@Override
public String read(JsonReader in) throws IOException {
JsonToken peek = in.peek(); // 獲取下一個jsontoken而不消耗它
if (peek == JsonToken.NULL) {
in.nextNull();
return null;
}
/* coerce booleans to strings for backwards compatibility */
if (peek == JsonToken.BOOLEAN) {
return Boolean.toString(in.nextBoolean()); // 若是時布爾值,則轉化爲String
}
return in.nextString(); // 從json串中獲取這個String類型的value並消耗它
}
@Override
public void write(JsonWriter out, String value) throws IOException {
out.value(value); // 不作任何處理直接寫入Json串
}
}
複製代碼
到這裏,關於Gson的TypeAdapter的原理也就講得差很少了,回顧一下,由於Type有兩類,對應的TypeAdapter也有兩類,一類是ReflectiveTypeAdapter,針對複合類型,它的做用是把複合類型拆解成基本類型,另外一類是針對基本類型的TypeAdapter,實現對應基本類型的Json串讀寫工做。而Gson本質上就是按照這兩類TypeAdapter來完成Json解析的。
能夠說,到這裏,咱們如今對Gson的基本工做流程有了一個基本的認識。
事實上,文章到這裏結合上面的源碼剖析和簡化流程圖,咱們已經能夠比較比較真實的分析出Gson的執行邏輯了。
Gson反序列化的平常用法:
UserInfo userInfo = getUserInfo();
Gson gson = new Gson();
String jsonStr = getJsonData();
UserInfo user = gson.fromJson(jsonStr,UserInfo.class); // 反序列化
複製代碼
gson.fromJson(jsonStr,UserInfo.class)方法內部真實的代碼執行流程大體以下:
咱們描述的這個流程和Gson代碼真實的執行流程已經沒太大的區別了。
Gson中除了適配器模式以外最重要的設計模式,可能就是工廠模式吧。由於Gson中衆多的TypeAdapter都是經過工廠模式統一建立的:
public interface TypeAdapterFactory {
// 建立TypeAdapter的接口
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
}
複製代碼
咱們能夠看看ReflectiveTypeAdapterFactory的實現
// ReflectiveTypeAdapterFactory的實現
public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
Class<? super T> raw = type.getRawType();
// 只要是Object的子類,就能匹配上
if (!Object.class.isAssignableFrom(raw)) {
// it's a primitive! return null; } ObjectConstructor<T> constructor = constructorConstructor.get(type); return new Adapter<T>(constructor, getBoundFields(gson, type, raw)); } } 複製代碼
Gson在其構造方法中,就提早把全部的TypeAdapterFactory放在緩存列表中。
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy,
final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
int timeStyle, List<TypeAdapterFactory> builderFactories,
List<TypeAdapterFactory> builderHierarchyFactories,
List<TypeAdapterFactory> factoriesToBeAdded) {
...
...
...
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
// built-in type adapters that cannot be overridden
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);
// the excluder must precede all adapters that handle user-defined types
factories.add(excluder);
// users type adapters
factories.addAll(factoriesToBeAdded);
// type adapters for basic platform types
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);
TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
factories.add(TypeAdapters.newFactory(double.class, Double.class,
doubleAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.newFactory(float.class, Float.class,
floatAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.NUMBER_FACTORY);
factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_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.CURRENCY_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.CLASS_FACTORY);
// type adapters for composite and user-defined types
factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
factories.add(TypeAdapters.ENUM_FACTORY);
// 注意,ReflectiveTypeAdapterFactor是要最後添加的
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
this.factories = Collections.unmodifiableList(factories);
}
複製代碼
這裏咱們可以看到,ReflectiveTypeAdapterFactor最後被添加進去的,由於這裏的添加順序是有講究的。咱們看看getAdapter(type)方法就能知道。
getAdapter(type)這個方法就是gson經過type尋找到對應的TypeAdapter,這是Gson中很是重要的一個方法。
// 經過Type獲取TypeAdapter
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
try {
// 遍歷緩存中全部的TypeAdapterFactory,
for (TypeAdapterFactory factory : factories) {
//若是類型匹配,則create()將會返回一個TypeAdapter,不然爲nulll
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
// candidate不爲null,證實找到類型匹配的TypeAdapter.
return candidate;
}
}
throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
}
}
複製代碼
ReflectiveTypeAdapterFactory之因此在緩存列表的最後一個,就是由於它能匹配幾乎任何類型,所以,咱們爲一個類型遍歷時,只能先判斷它是否是基本類型,若是都不成功,最後再使用ReflectiveTypeAdapterFactor進行判斷。
這就是Gson中用到的工廠模式。
咱們從新回到getAdapter(type)這個方法,這個方法裏面有一些比較難理解的代碼
// 經過Type獲取TypeAdapter
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
// typeTokenCache是Gson的一個Map類型的緩存結構
// 0,首先嚐試從緩存中獲取是否有對應的TypeAdapter
TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
if (cached != null) {
return (TypeAdapter<T>) cached;
}
// 1,alls 是Gson內部的ThreadLocal變量,用於保存一個Map對象
// map對象也緩存了一種FutureTypeAdapter
Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
boolean requiresThreadLocalCleanup = false;
if (threadCalls == null) {
threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
calls.set(threadCalls);
requiresThreadLocalCleanup = true;
}
//2,若是從ThreadLocal內部的Map中找到緩存,則直接返回
// the key and value type parameters always agree
FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
if (ongoingCall != null) {
return ongoingCall;
}
try {
建立一個FutureTypeAdapter
FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
// 緩存
threadCalls.put(type, call);
for (TypeAdapterFactory factory : factories) {
// 遍歷全部的TypeAdapterFactory
TypeAdapter<T> candidate = factory.create(this, type);
if (candidate != null) {
// 3, 設置委託的TypeAdapter
call.setDelegate(candidate);
// 緩存到Gson內部的Map中,
typeTokenCache.put(type, candidate);
return candidate;
}
}
//若是遍歷都沒有找到對應的TypeAdapter,直接拋出異常
throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
} finally {
// 4,移除threadCalls內部緩存的 FutureTypeAdapter
threadCalls.remove(type);
if (requiresThreadLocalCleanup) {
//ThreadLocal移除該線程環境中的Map
calls.remove();
}
}
}
複製代碼
上述代碼比較難以理解的地方我標註了序號,用於後面解釋代碼
方法裏出現了FutureTypeAdapter這個TypeAdapter,彷佛很奇怪,由於它沒有FutureTypeAdapterFactory這個工廠類,咱們先來看看 FutureTypeAdapter的內部構造
static class FutureTypeAdapter<T> extends TypeAdapter<T> {
private TypeAdapter<T> delegate;
public void setDelegate(TypeAdapter<T> typeAdapter) {
if (delegate != null) {
throw new AssertionError();
}
delegate = typeAdapter;
}
@Override public T read(JsonReader in) throws IOException {
if (delegate == null) {
throw new IllegalStateException();
}
return delegate.read(in);
}
@Override public void write(JsonWriter out, T value) throws IOException {
if (delegate == null) {
throw new IllegalStateException();
}
delegate.write(out, value);
}
}
複製代碼
這是一個明顯的委派模式(也可稱爲代理模式)的包裝類。咱們都知道委託模式的功能是:隱藏代碼具體實現,經過組合的方式一樣的功能,避開繼承帶來的問題。可是在這裏使用委派模式彷佛並非基於這些考慮。而是爲了不陷入無限遞歸致使對棧溢出的崩潰。
爲何這麼說呢?咱們來舉個例子:
// 定義一個帖子的實體
public class Article {
// 表示帖子中連接到其餘的帖子
public Article linkedArticle;
.....
.....
.....
}
複製代碼
Article類型中有一個linkedArticle屬性,它的類型仍是Article,根據咱們以前總結的簡化流程圖:
你會發現這裏有一個死循環,或者說沒法終結的遞歸。爲了不這個問題,因此先建立一個代理類,等到遞歸遇到一樣的類型時直接複用返回,避免無限遞歸。也就是註釋2那段代碼的用意,在註釋3處,再將建立成功的TypeAdapter設置到代理類中。就基本解決這個問題了。
固然說基本解決,是由於還要考慮多線程的環境,因此就出現了ThreadLocal這個線程局部變量,這保證了它只會在單個線程中緩存,並且會在單次Json解析完成後移出緩存。見上文註釋1和註釋4。這是由於無限遞歸只會發生在單次Json解析中,並且Gson內部已經有了一個TypeAdapterde 全局緩存(typeTokenCache),見註釋0.
潛在的遞歸循環: gson.getAdapter(type) ---> (ReflectiveTypeAdapterFactory)factory.create(this, type) ---> getBoundFields() ---> createBoundField() ---> (Gson)context.getAdapter(fieldType)
上文只講到了Gson本身內部是如何實現Json解析的,其實Gson也提供了一些自定義解析的接口。主要是兩種:
那麼,二者有什麼區別呢?
追求效率更高,選第一種,想要操做更簡單,實現更靈活,選第二種。
爲何這麼說?舉個例子,假設咱們須要爲Article這個JavaBean自定義解析,若是咱們選擇繼承TypeAdapter的話,須要先實現TypeAdapter,而後註冊。
// 繼承TypeAdapter,實現抽象方法
public class ArticleTypeAdapter extends TypeAdapter<Article>{
@Override
public void write(JsonWriter out, Article value) throws IOException {
// 實現把Article中的實體數據的寫入到JsonWriter中,實現序列化
}
@Override
public Article read(JsonReader in) throws IOException {
// 須要建立Article對象
// 把 JsonReader中的json串讀出來,並設置到Article對象中
return null;
}
}
...
...
// 註冊
Gson mGson = new GsonBuilder()
.registerTypeAdapter(Article.class, new ArticleTypeAdapter<>())//實際上註冊到Gson的factories列表中
.create();
複製代碼
這樣就實現了自定義的Json解析,這種方式的讀寫效率很高,可是不太靈活,由於必需要同時實現序列化和反序列化的工做。
而實現JsonSerializer/JsonDeserializer接口這種方式相對更簡單
//JsonSerializer(json序列話)/JsonDeserializer(反序列化)可按需實現
public class ArticleTypeAdapter implements JsonDeserializer<Article> {
@Override
public Article deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// 須要建立Article對象
// 並從JsonElement中把封裝好的Json數據結構讀出來,並設置到Article對象中
return null;
}
}
// 註冊
Gson mGson = new GsonBuilder()
.registerTypeAdapter(Article.class, new ArticleTypeAdapter<>())//實際上註冊到Gson的factories列表中
.create();
複製代碼
咱們能夠看到,二者的區別,是後者更加靈活,序列化/返序列化可按需選擇,並且它使用了JsonElement對Json數據進行再封裝,從而使咱們操做Json數據更加簡單。不過正是由於使用了 JsonElement這種對Json數據再封裝的類,而不是更加原始的JsonReader致使了代碼執行效率的下降。
如上圖所示,本質上就是多了一箇中間層,致使解析效率的下降。不過話說回來,只要不是很是大批量複雜結構的連續解析,這種效率差別咱們能夠忽略不計,所以平常的開發,你們經過JsonSerializer/JsonDeserializer接口來實現自定義解析是一個相對更好的選擇。