摘要:接上篇三和在進(jìn)行的序列化和反序列化源碼解析之前先了解一下其主體工具類。是中用于序列化的主體。同時(shí)為了兼顧性能做了很多有意思的設(shè)計(jì),比如獲取適配器的時(shí)候的雙緩存設(shè)計(jì),應(yīng)該是為了提高解析器的復(fù)用效率,具體有待研究。
接上篇 三 JsonReader 和 JsonWriter
在進(jìn)行 json 的序列化和反序列化源碼解析之前先了解一下其主體工具類。
1 JsonReaderJsonReader 是 Gson 中用于 json 反序列化的主體。
在 Gson 包中可以不使用 Gson 門面而多帶帶使用 JsonReader 進(jìn)行 json 的反序列化:
public static void main(String[] args){ //json 字符串 String json = "{"name":"zhangsan","age":18}"; //使用 StringReader 包裝字符串 StringReader strReader = new StringReader(json); //使用 JsonReader 包裝 StringReader JsonReader jsonReader = new JsonReader(strReader); //創(chuàng)建一個(gè)參數(shù)均為空的目標(biāo)對(duì)象 Person p = new Person(); try { //beginObject(...) 方法用于告訴 jsonReader 開始讀取一個(gè) object jsonReader.beginObject(); //while 循環(huán)讀取 while(jsonReader.hasNext()){ //讀取一個(gè) json 的 key 值 String name = jsonReader.nextName(); switch (name){ case "name": p.setName(jsonReader.nextString()); //讀取一個(gè) String 作為 value,存入對(duì)象中 break; case "age": p.setAge(jsonReader.nextInt()); //讀取一個(gè) int 作為 value,存入對(duì)象中 break; } } jsonReader.endObject(); } catch (IOException e) { e.printStackTrace(); } System.out.println("名字:" + p.getName()); System.out.println("年齡:" +p.getAge()) }
JsonReader 的構(gòu)造方法:
//JsonReader.class public JsonReader(Reader in) { if (in == null) { throw new NullPointerException("in == null"); } //傳入的 Reader 中保存著要讀取的 json 主體 //此處比較常用的是 StringReader,但是也可以是 FileReader 等其它 Reader 接口的實(shí)現(xiàn)類 this.in = in; }
JsonReader 僅此一個(gè)構(gòu)造方法,創(chuàng)建對(duì)象均調(diào)用此方法。
先來(lái)看一下 JsonReader 中非常重要的一個(gè)非公開方法 doPeek():
//JsonReader.class int doPeek() throws IOException { //stack 是一個(gè)定義在 JsonReader 中的 int 數(shù)組,作為 JsonReader 的指令集存在,用于控制變量 peeked 的狀態(tài) //在 JsonReader 初始化的時(shí)候會(huì)將 stack 的第一個(gè)元素變成6,其余均為0 //6的意思根據(jù)官方注釋為 "No object or array has been started"(還沒開始讀取對(duì)象或列表) //6作為常量保存在 JsonScope 中,JsonScope 中還保存了很多代表指令的常量,下列會(huì)用到 //stackSize 是 stack 的有效元素計(jì)數(shù)器,初始化時(shí) stackSize = 1,即只有第一個(gè)元素是有效的 int peekStack = stack[stackSize - 1]; //JsonScope.EMPTY_ARRAY = 1 if (peekStack == JsonScope.EMPTY_ARRAY) { //JsonScope.NONEMPTY_ARRAY = 2 stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY; } else if (peekStack == JsonScope.NONEMPTY_ARRAY) { //在第一次調(diào)用 nextNonWhitespace(true) 方法的時(shí)候,json 字符串會(huì)被轉(zhuǎn)存為一個(gè) char 數(shù)組 //該方法以 int 值的形式返回下一個(gè)要解析的 char 對(duì)象 int c = nextNonWhitespace(true); switch (c) { case "]": //peeked 是 JsonReader 中最重要的用來(lái)狀態(tài)控制的 int 變量 //peeker 和 stack 會(huì)協(xié)同控制 JsonReader 的邏輯行為 return peeked = PEEKED_END_ARRAY; //PEEKED_END_ARRAY = 4 case ";": //檢查標(biāo)準(zhǔn)協(xié)議選項(xiàng),json 標(biāo)準(zhǔn)中的符號(hào)沒有分號(hào) //所以在 lenient = false 的時(shí)候就會(huì)報(bào)錯(cuò) checkLenient(); case ",": break; default: throw syntaxError("Unterminated array"); } //JsonScope.EMPTY_OBJECT = 3,JsonScope.NONEMPTY_OBJECT = 5 } else if (peekStack == JsonScope.EMPTY_OBJECT || peekStack == JsonScope.NONEMPTY_OBJECT) { //JsonScope.DANGLING_NAME = 4 stack[stackSize - 1] = JsonScope.DANGLING_NAME; if (peekStack == JsonScope.NONEMPTY_OBJECT) { int c = nextNonWhitespace(true); switch (c) { case "}": return peeked = PEEKED_END_OBJECT; //PEEKED_END_OBJECT = 2 case ";": checkLenient(); case ",": break; default: throw syntaxError("Unterminated object"); } } int c = nextNonWhitespace(true); switch (c) { case """: return peeked = PEEKED_DOUBLE_QUOTED_NAME; //PEEKED_DOUBLE_QUOTED_NAME = 13 case """: checkLenient(); return peeked = PEEKED_SINGLE_QUOTED_NAME; //PEEKED_SINGLE_QUOTED_NAME = 12 case "}": if (peekStack != JsonScope.NONEMPTY_OBJECT) { return peeked = PEEKED_END_OBJECT; } else { throw syntaxError("Expected name"); } default: checkLenient(); pos--; if (isLiteral((char) c)) { return peeked = PEEKED_UNQUOTED_NAME; //PEEKED_UNQUOTED_NAME = 14 } else { throw syntaxError("Expected name"); } } } else if (peekStack == JsonScope.DANGLING_NAME) { stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT; int c = nextNonWhitespace(true); switch (c) { case ":": break; case "=": checkLenient(); //buffer 是儲(chǔ)存 json 字符串的 char 數(shù)組 //pos 是已經(jīng)讀取到字符的數(shù)量指針 //limit 是 buffer 的可用部分的總長(zhǎng) if ((pos < limit || fillBuffer(1)) && buffer[pos] == ">") { pos++; } break; default: throw syntaxError("Expected ":""); } //JsonScope.EMPTY_DOCUMENT = 6 //第一次進(jìn)入方法的時(shí)候,會(huì)進(jìn)入這個(gè) if 語(yǔ)句中 } else if (peekStack == JsonScope.EMPTY_DOCUMENT) { //檢查標(biāo)準(zhǔn)化協(xié)議相關(guān) if (lenient) { consumeNonExecutePrefix(); } //JsonScope.NONEMPTY_DOCUMENT = 7 stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT; } else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) { int c = nextNonWhitespace(false); if (c == -1) { return peeked = PEEKED_EOF; } else { checkLenient(); pos--; } //JsonScope.CLOSED = 8 } else if (peekStack == JsonScope.CLOSED) { throw new IllegalStateException("JsonReader is closed"); } //在這里獲取到了下一個(gè)要解析的 char 的 int 值 int c = nextNonWhitespace(true); //進(jìn)入 switch 去進(jìn)行定位,定位到了之后修改 peeked 的狀態(tài) switch (c) { case "]": if (peekStack == JsonScope.EMPTY_ARRAY) { return peeked = PEEKED_END_ARRAY; } case ";": case ",": if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) { checkLenient(); pos--; return peeked = PEEKED_NULL; } else { throw syntaxError("Unexpected value"); } case """: checkLenient(); return peeked = PEEKED_SINGLE_QUOTED; case """: return peeked = PEEKED_DOUBLE_QUOTED; case "[": return peeked = PEEKED_BEGIN_ARRAY; case "{": return peeked = PEEKED_BEGIN_OBJECT; default: pos--; } //peekKeyword() 方法會(huì)從 buffer 數(shù)組里獲取下一個(gè) char //然后根據(jù)這個(gè)字符判斷下一個(gè)要處理的字符串是不是 true、false、null 等特殊字符 //如果不是,會(huì)返回 result = PEEKED_NONE int result = peekKeyword(); if (result != PEEKED_NONE) { //不等于 PEEKED_NONE,證明下一個(gè)確實(shí)是特殊字符 return result; } //peekNumber() 方法和上述 peekKeyword() 方法很類似 //用于判斷下一個(gè)要處理的字符串是否是數(shù)字 result = peekNumber(); if (result != PEEKED_NONE) { return result; } //isLiteral(buffer[pos]) 用于判斷下一個(gè)字符是否是特殊符 //比如 換行符、井號(hào)、括號(hào) 等 //如果是 換行符 的話這里就會(huì)拋出錯(cuò)誤 if (!isLiteral(buffer[pos])) { throw syntaxError("Expected value"); } checkLenient(); return peeked = PEEKED_UNQUOTED; //PEEKED_UNQUOTED = 10 }
方法雖然比較長(zhǎng),但是代碼其實(shí)比較簡(jiǎn)單,本質(zhì)上是根據(jù) stack 指令去修改 peeked 的值,從而達(dá)到狀態(tài)控制的效果。
再來(lái)看 beginObject() 方法:
//JsonReader.class public void beginObject() throws IOException { int p = peeked; //初始化時(shí) peeked = PEEKED_NONE //在 doPeek() 方法中會(huì)修改成 PEEKED_BEGIN_OBJECT,即開始一個(gè) Object 的序列化 if (p == PEEKED_NONE) { p = doPeek(); } if (p == PEEKED_BEGIN_OBJECT) { //push(...) 方法會(huì)檢查 stack 數(shù)組的容積,適時(shí)進(jìn)行擴(kuò)容,并把傳入的指令存放到數(shù)組中 //此處將 EMPTY_OBJECT 指令存入到 stack 中 push(JsonScope.EMPTY_OBJECT); //將 peeked 狀態(tài)初始化 peeked = PEEKED_NONE; } else { throw new IllegalStateException("Expected BEGIN_OBJECT but was " + peek() + locationString()); } }
再來(lái)看 nextName() 方法:
//JsonReader.class public String nextName() throws IOException { //老樣子進(jìn)行 peeked 的狀態(tài)獲取 int p = peeked; if (p == PEEKED_NONE) { p = doPeek(); } String result; //在這里通過(guò) if 語(yǔ)句和 peeked 定位 json 的 key 是用單引號(hào)還是雙引號(hào)包裹的 //result 就是 key 的字符串 if (p == PEEKED_UNQUOTED_NAME) { result = nextUnquotedValue(); } else if (p == PEEKED_SINGLE_QUOTED_NAME) { result = nextQuotedValue("""); } else if (p == PEEKED_DOUBLE_QUOTED_NAME) { result = nextQuotedValue("""); } else { throw new IllegalStateException("Expected a name but was " + peek() + locationString()); } //將 peeked 狀態(tài)初始化 peeked = PEEKED_NONE; //pathNames 是一個(gè)用來(lái)儲(chǔ)存所有 key 的字符串的數(shù)組 pathNames[stackSize - 1] = result; return result; }
nextQuotedValue(...) 方法里實(shí)際上是比較繁瑣的字符串處理,在這里暫時(shí)不展開了。
hasNext() 和 nextString() 方法其實(shí)都和 nextName() 方法差不多,本質(zhì)上都是根據(jù) peeked 的值去進(jìn)入不同的 if 語(yǔ)句來(lái)處理字符串。
2 JsonWriterJsonWriter 是 Gson 中用于 json 序列化的主體。
和 JsonReader 一樣,也可以不使用 Gson 門面而多帶帶使用 JsonWriter 進(jìn)行 json 的序列化:
public static void main(String[] args){ //組裝 bean Person person = new Person(); person.setName("zhangsan"); person.setAge(18); //創(chuàng)建一個(gè) StringWriter,本質(zhì)是 StringBuffer 的封裝 StringWriter writer = new StringWriter(); //用 JsonWriter 去封裝 StringWriter JsonWriter jsonWriter = new JsonWriter(writer); try { //啟動(dòng)一個(gè) object 的寫入 jsonWriter.beginObject(); //寫入 key-value jsonWriter.name("name").value(person.getName()); jsonWriter.name("age").value(person.getAge()); //結(jié)束命令 jsonWriter.endObject(); //將 JsonWriter 里的數(shù)據(jù)存入到 StringWriter 中 jsonWriter.flush(); } catch (IOException e) { e.printStackTrace(); } System.out.println(writer.toString()); }
JsonWriter 的構(gòu)造方法:
//JsonWriter.class public JsonWriter(Writer out) { if (out == null) { throw new NullPointerException("out == null"); } this.out = out; }
追蹤一下 beginObject() 方法:
//JsonWriter.class public JsonWriter beginObject() throws IOException { //這個(gè)方法主要的作用是在不同的 object 之間加逗號(hào) //如果是起始第一個(gè) object 就不需要了,會(huì)直接跳過(guò) writeDeferredName(); return open(EMPTY_OBJECT, "{"); }
繼續(xù)追蹤 open(...) 方法:
//JsonWriter.class private JsonWriter open(int empty, String openBracket) throws IOException { //該方法會(huì)使用 stack 中最新的指令進(jìn)行操作 beforeValue(); //push(...) 方法會(huì)檢查 stack 數(shù)組的容積,適時(shí)進(jìn)行擴(kuò)容,并把傳入的指令存放到數(shù)組中 push(empty); //寫入字符串 out.write(openBracket); return this; }
JsonWriter 中沒有 JsonReader 中那么復(fù)雜的指令操作,所以沒有引入 peeked 變量,僅僅使用 stack 數(shù)組來(lái)控制狀態(tài)。
stack 的控制封裝在 beforeValue() 方法中:
//JsonWriter.class private void beforeValue() throws IOException { //peek() 方法會(huì)根據(jù) stack 數(shù)組的指令獲取到下一個(gè)要操作的字符類型 switch (peek()) { case NONEMPTY_DOCUMENT: if (!lenient) { throw new IllegalStateException( "JSON must have only one top-level value."); } case EMPTY_DOCUMENT: //replaceTop(...) 方法會(huì)將 stack 最新的指令更新成傳入的參數(shù) replaceTop(NONEMPTY_DOCUMENT); break; case EMPTY_ARRAY: replaceTop(NONEMPTY_ARRAY); //換行 newline(); break; case NONEMPTY_ARRAY: out.append(","); newline(); break; case DANGLING_NAME: //separator 即為 ":" (冒號(hào)) out.append(separator); replaceTop(NONEMPTY_OBJECT); break; default: throw new IllegalStateException("Nesting problem."); } }
來(lái)看一下 name(...) 方法:
//JsonWriter.class public JsonWriter name(String name) throws IOException { if (name == null) { throw new NullPointerException("name == null"); } if (deferredName != null) { throw new IllegalStateException(); } if (stackSize == 0) { throw new IllegalStateException("JsonWriter is closed."); } //這一行代碼中會(huì)暫時(shí)將傳入的 name 參數(shù)保存在一個(gè)全局變量中, //所以 JsonWriter 在調(diào)用 value(...) 方法之前不能再調(diào)用 name(...) 方法了,不然在上方的判斷中會(huì)報(bào)錯(cuò) deferredName = name; return this; }
來(lái)看一下 value(...) 方法:
//JsonWriter.class public JsonWriter value(String value) throws IOException { if (value == null) { //nullValue() 方法會(huì)在 value 值的地方存入一個(gè) null return nullValue(); } //這一方法會(huì)將 之前保存在 deferredName 中的字符串寫入到 writer 中 //方法中會(huì)處理加逗號(hào)、將 deferredName 變量清空等問(wèn)題 //核心是調(diào)用 string(...) 方法寫入 writeDeferredName(); //更新 stack 指令 beforeValue(); //和上方寫入 deferredName 一樣,此處調(diào)用寫入 value string(value); return this; }
總的來(lái)說(shuō) JsonWriter 比 JsonReader 簡(jiǎn)單,簡(jiǎn)要描述一下不過(guò)多展開。
四 JSON 字符串轉(zhuǎn) Bean該 part 的起點(diǎn):
Person person = gson.fromJson(json,Person.class);
追蹤 fromJson(...) 方法:
//Gson.class publicT fromJson(String json, Class classOfT) throws JsonSyntaxException { //將字符串轉(zhuǎn)成 object 的主體方法 //3.1 Object object = fromJson(json, (Type) classOfT); return Primitives.wrap(classOfT).cast(object); }
先來(lái)看一下上述的第二行代碼:
return Primitives.wrap(classOfT).cast(object);
Primitives.wrap(...) 方法的實(shí)現(xiàn):
//Primitives.class public staticClass wrap(Class type) { //PRIMITIVE_TO_WRAPPER_TYPE 是一個(gè) map 對(duì)象 //$Gson$Preconditions.checkNotNull(...) 用來(lái)效驗(yàn) type 不為空 @SuppressWarnings("unchecked") Class wrapped = (Class ) PRIMITIVE_TO_WRAPPER_TYPE.get( $Gson$Preconditions.checkNotNull(type)); //如果 map 中不存在 type 為 key 的值,則返回 type,否則返回取到的 value return (wrapped == null) ? type : wrapped; }
PRIMITIVE_TO_WRAPPER_TYPE 是一個(gè)定義在 Primitives 中的 map 對(duì)象:
//Primitives.class private static final Map, Class>> PRIMITIVE_TO_WRAPPER_TYPE;
PRIMITIVE_TO_WRAPPER_TYPE 中主要存放了 float、int、double 等原始類型的 class:
//Primitives.class static { Map, Class>> primToWrap = new HashMap , Class>>(16); Map , Class>> wrapToPrim = new HashMap , Class>>(16); //以下代碼是將原始類型和包裝類型存入兩個(gè) map 的過(guò)程 add(primToWrap, wrapToPrim, boolean.class, Boolean.class); add(primToWrap, wrapToPrim, byte.class, Byte.class); add(primToWrap, wrapToPrim, char.class, Character.class); add(primToWrap, wrapToPrim, double.class, Double.class); add(primToWrap, wrapToPrim, float.class, Float.class); add(primToWrap, wrapToPrim, int.class, Integer.class); add(primToWrap, wrapToPrim, long.class, Long.class); add(primToWrap, wrapToPrim, short.class, Short.class); add(primToWrap, wrapToPrim, void.class, Void.class); //Collections.unmodifiableMap(...) 返回一個(gè)只能閱讀不能修改的 map //原始類型作為 key,包裝類型作為 value PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap); //包裝類型作為 value,原始類型作為 key WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim); }
由此可見 Primitives.wrap(...) 本質(zhì)上是判斷傳入的 type 是否是原始類型,如果是,則會(huì)轉(zhuǎn)換成包裝類型并返回。
至于 Primitives.wrap(classOfT).cast(object) 中的 cast(...),則是定義在 Class 中的方法:
//Class.class @HotSpotIntrinsicCandidate public T cast(Object obj) { //isInstance(...) 方法等價(jià)于關(guān)鍵詞 instanceof //如果 obj 不為 null 且 不為該 Class 對(duì)象的子類,則會(huì)拋出錯(cuò)誤 if (obj != null && !isInstance(obj)) throw new ClassCastException(cannotCastMsg(obj)); return (T) obj; }
代碼比較簡(jiǎn)單,本質(zhì)上就是強(qiáng)轉(zhuǎn)類型。
再來(lái)看這行代碼:
Object object = fromJson(json, (Type) classOfT);
追蹤具體實(shí)現(xiàn):
//Gson.class publicT fromJson(String json, Type typeOfT) throws JsonSyntaxException { //非 null 判斷 if (json == null) { return null; } //StringReader 是一個(gè) jdk 中存在的 String 和 Reader 的關(guān)聯(lián)封裝類 StringReader reader = new StringReader(json); //主體功能實(shí)現(xiàn)方法 T target = (T) fromJson(reader, typeOfT); //返回一個(gè)指定泛型的對(duì)象 return target; }
繼續(xù)追蹤重載方法:
//Gson.class publicT fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException { //初始化一個(gè) JsonReader JsonReader jsonReader = newJsonReader(json); //主體功能實(shí)現(xiàn)方法 T object = (T) fromJson(jsonReader, typeOfT); //在整個(gè)反序列化過(guò)程結(jié)束之前效驗(yàn) jsonReader 的 peeked 的狀態(tài) //如果 peeker 未處于結(jié)束狀態(tài),則會(huì)報(bào)錯(cuò) assertFullConsumption(object, jsonReader); return object; }
繼續(xù)追蹤重載方法:
//Gson.class publicT fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { boolean isEmpty = true; boolean oldLenient = reader.isLenient(); //打開 reader 的標(biāo)準(zhǔn)化檢驗(yàn) reader.setLenient(true); try { //此處相當(dāng)于調(diào)用了一次 JsonReader 中的 doPeek() 方法 reader.peek(); isEmpty = false; //TypeToken 本質(zhì)上是 Class 的增強(qiáng)封裝類 TypeToken typeToken = (TypeToken ) TypeToken.get(typeOfT); //根據(jù) TypeToken 獲取對(duì)應(yīng)的能夠處理其類型的 TypeAdapter TypeAdapter typeAdapter = getAdapter(typeToken); //反射創(chuàng)建 object T object = typeAdapter.read(reader); return object; } catch (EOFException e) { if (isEmpty) { return null; } throw new JsonSyntaxException(e); } catch (IllegalStateException e) { throw new JsonSyntaxException(e); } catch (IOException e) { throw new JsonSyntaxException(e); } catch (AssertionError e) { throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e); } finally { reader.setLenient(oldLenient); } }
先來(lái)看一下 getAdapter(...) 方法:
//Gson.class publicTypeAdapter getAdapter(TypeToken type) { //typeTokenCache 是 Gson 中的一個(gè) map 對(duì)象,用于儲(chǔ)存 TypeAdapter //typeTokenCache 是一個(gè) Gson 中各個(gè)線程公用的一個(gè)緩存池 TypeAdapter> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type); if (cached != null) { //如果本身就有儲(chǔ)存了,就直接返回 return (TypeAdapter ) cached; } //calls 是一個(gè) ThreadLocal 對(duì)象 //ThreadLocal 是 Gson 中單個(gè)線程使用的緩存池,在里面存入的對(duì)象會(huì)在 finally 代碼塊中清空掉 Map , FutureTypeAdapter>> threadCalls = calls.get(); //判斷是否需要清空 ThreadLocal boolean requiresThreadLocalCleanup = false; if (threadCalls == null) { threadCalls = new HashMap , FutureTypeAdapter>>(); calls.set(threadCalls); //這里存入了對(duì)象,所以需要清空 ThreadLocal requiresThreadLocalCleanup = true; } //如果存在對(duì)象,就會(huì)在這里取用出來(lái)并返回 //FutureTypeAdapter 是一個(gè)門面模式的應(yīng)用,其實(shí)本質(zhì)是使用內(nèi)部的 TypeAdapter 去處理業(yè)務(wù) //如果內(nèi)部沒有存入實(shí)際處理業(yè)務(wù)的 TypeAdapter,就會(huì)報(bào)錯(cuò) FutureTypeAdapter ongoingCall = (FutureTypeAdapter ) threadCalls.get(type); if (ongoingCall != null) { return ongoingCall; } try { FutureTypeAdapter call = new FutureTypeAdapter (); threadCalls.put(type, call); //這個(gè)方法的主體是這個(gè) for 循環(huán),用于從 Gson 初始化的時(shí)候儲(chǔ)存的列表中獲取到對(duì)應(yīng)的 TypeAdapter for (TypeAdapterFactory factory : factories) { //TypeAdapter 的 create(...) 方法對(duì)于不是對(duì)應(yīng)類型的參數(shù)會(huì)返回 null TypeAdapter candidate = factory.create(this, type); if (candidate != null) { //在此處會(huì)存入業(yè)務(wù)處理的 TypeAdapter call.setDelegate(candidate); //在此處存入公用緩存 typeTokenCache.put(type, candidate); return candidate; } } throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type); } finally { //清除 ThreadLocal 緩存 threadCalls.remove(type); if (requiresThreadLocalCleanup) { calls.remove(); } } }
到此為止 json 的反序列化就基本完畢了.
五 Bean 轉(zhuǎn) JSON 字符串該 part 的起點(diǎn):
String json2 = gson.toJson(person);
追蹤 toJson(...) 方法:
//Gson.class public String toJson(Object src) { if (src == null) { return toJson(JsonNull.INSTANCE); } return toJson(src, src.getClass()); }
toJson(JsonNull.INSTANCE) 方法最后會(huì)輸出一個(gè) null 字符串,不多展開了。
繼續(xù)來(lái)關(guān)注下方主要實(shí)現(xiàn)邏輯:
//Gson.class public String toJson(Object src, Type typeOfSrc) { //新建一個(gè) StringWriter StringWriter writer = new StringWriter(); //主要邏輯 toJson(src, typeOfSrc, writer); //返回 return writer.toString(); }
繼續(xù)追蹤主要邏輯方法:
//Gson.class public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException { try { //這里將 StringWriter 包裝成了 JsonWriter JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer)); //主要邏輯 toJson(src, typeOfSrc, jsonWriter); } catch (IOException e) { throw new JsonIOException(e); } }
繼續(xù)追蹤主要邏輯方法:
//Gson.class public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException { //獲取適配的 TypeAdapter TypeAdapter> adapter = getAdapter(TypeToken.get(typeOfSrc)); //下方代碼均為儲(chǔ)存并存入一些標(biāo)準(zhǔn)化的設(shè)置 boolean oldLenient = writer.isLenient(); writer.setLenient(true); boolean oldHtmlSafe = writer.isHtmlSafe(); writer.setHtmlSafe(htmlSafe); boolean oldSerializeNulls = writer.getSerializeNulls(); writer.setSerializeNulls(serializeNulls); //寫入 try { ((TypeAdapter
基本的邏輯都在上面講過(guò)了,不贅述。
到此為止 json 的序列化就基本完畢了。
四 總結(jié)Gson 的代碼封裝很薄,本身不難,但是為了照顧兼容性,代碼中存在很多條件判斷,導(dǎo)致代碼看上去很繁瑣。同時(shí)為了兼顧性能做了很多有意思的設(shè)計(jì),比如獲取適配器的時(shí)候的雙緩存設(shè)計(jì),應(yīng)該是為了提高解析器的復(fù)用效率,具體有待研究。
總結(jié)一下 Gson 的基本思路:
· 解析器(Gson)將使用者傳入的字符串或?qū)ο蟠嫒胱x取器(Reader)或者寫入器(Writer)中
· 解析器遍歷并獲取能夠處理對(duì)應(yīng)類型的適配器工廠(TypeAdapterFactory)
· 適配器工廠會(huì)創(chuàng)建出對(duì)應(yīng)類型的適配器(TypeAdapter)
· 解析器將閱讀器或?qū)懭肫鹘唤o適配器
· 適配器自行通過(guò)業(yè)務(wù)邏輯操作讀取器或?qū)懭肫?,輸出需要的結(jié)果
· 解析器接收此輸出,并交給使用者
五 一點(diǎn)嘮叨· Gson 太過(guò)強(qiáng)調(diào)功能的全面,解析器的初始化非常復(fù)雜
· JsonReader 的狀態(tài)控制太過(guò)復(fù)雜和精密,筆者到現(xiàn)在也沒全部弄清楚
· 在本篇源碼解析中,Gson 內(nèi)部還有一些拓展功能,比如 JsonElement、JsonParser 等的工具類沒有提及
· 僅為個(gè)人的學(xué)習(xí)筆記,可能存在錯(cuò)誤或者表述不清的地方,有緣補(bǔ)充
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72959.html
摘要:版本版本簡(jiǎn)介是谷歌開源的解析工具。其實(shí)幾款產(chǎn)品的差別都很細(xì)微,有谷歌的信仰加成,所以在這里進(jìn)行一次源碼分析。至于和會(huì)在后續(xù)進(jìn)行追蹤。 零 前期準(zhǔn)備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 Gson 版本 : gson 2.8.5 IDE : idea 2018.3 2 Gson 簡(jiǎn)介 Gson 是谷歌開源的 java json 解析工具。市場(chǎng)上同類的開源產(chǎn)品還有 F...
摘要:的前位數(shù)用來(lái)表示線程的數(shù)量,后面三位用來(lái)表示線程池的狀態(tài)。線程池的狀態(tài)有五種,分別是,根據(jù)單詞就能猜出大概。并且為了考慮性能問(wèn)題,線程池的設(shè)計(jì)沒有使用悲觀鎖關(guān)鍵字,而是大量使用了和機(jī)制。 零 前期準(zhǔn)備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 2 ThreadPoolExecutor ...
摘要:看下圖所示,摘自網(wǎng)絡(luò)的創(chuàng)建流程源碼分析實(shí)例是使用建造者模式通過(guò)類進(jìn)行創(chuàng)建的。創(chuàng)建了一個(gè)含有對(duì)象實(shí)例的,并返回給源碼分析添加一個(gè)調(diào)用適配器工廠,用于支持服務(wù)方法返回類型注意生產(chǎn)的是,那么又是什么呢可以看到源代碼如下所示,它是一個(gè)接口。 目錄介紹 1.首先回顧Retrofit簡(jiǎn)單使用方法 2.Retrofit的創(chuàng)建流程源碼分析 2.1 Retrofit對(duì)象調(diào)用Builder()源碼解...
摘要:六修改內(nèi)部類的方法這個(gè)的方法是對(duì)類型的數(shù)據(jù)進(jìn)行解析,我們判斷輸入的數(shù)據(jù)類型不是類型,就直接跳過(guò)解析,核心是在方法中插入方法。每一個(gè)類每一個(gè)內(nèi)部類每一個(gè)匿名內(nèi)部類,都會(huì)生成一個(gè)獨(dú)立的文件,如。 一、項(xiàng)目地址 項(xiàng)目地址:github-gson-plugin 二、ReaderTools解析 /** * Created by tangfuling on 2018/10/23. */ pu...
閱讀 1624·2021-11-24 09:39
閱讀 1182·2021-11-22 15:11
閱讀 2297·2021-11-19 11:35
閱讀 1683·2021-09-13 10:37
閱讀 2631·2021-09-03 10:47
閱讀 2234·2021-08-30 09:47
閱讀 1699·2021-08-20 09:39
閱讀 3007·2019-08-30 14:13