給你一組json數據結構,你把它解析出來到項目中,你會怎麼作?前端
// data1 sample { "code" : "1", "msg" : "Success", "data" : { "userid1" : { "name" : "Zhangsan", "sex" : "male" } } } // data2 sample { "code" : "1", "msg" : "Success", "data" : { "orderid1" : { "address" : "street 1", "pay" : "111.0", "productId" : "1342546" } } }
首先,code,msg,data 確定是固定結構,因此能夠抽象出一層 data 的變化,可使用泛型去適應變化;java
其次,data下的數據是 key -> object 的結構,若是直接object表示的話,又不友好了。若是不以object表示,針對不一樣的object又如何是好?答案是,再抽象一層泛型出來就好了;android
最終的數據結構就是這樣: ResponseEntity<T> ---> ResponseEntity<Map<String, T>> , 具體bean就不用寫了吧!git
其實作這一步的解析,仍是容易的。不過,具體怎麼作,就不必定了。web
另外一個問題,解析這些數據結構,我須要再封裝得簡單點,由於底層的數據訪問步驟都是同樣的,我不想重複造輪子!好比,我只須要在最上層轉入想要轉化的數據結構類型,就能夠獲得不同的數據對象!spring
這個固然很簡單,只須要使用泛型方法就好了。簡單示例以下:json
public class CapitalUtilsTest { @Test public void testInnerGenericAnalyze() { ResponseEntity<Map<String, OrderDetail>> result = parseMoreGenericParams(); System.out.println("result:" + result); } private <T> ResponseEntity<Map<String, T>> parseMoreGenericParams() { String json = "{\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}"; return JSONObject.parseObject(json, new TypeReference<ResponseEntity<Map<String, T>>>(){}); } } class ResponseEntity<T> { private String code; private String msg; private T data; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return "ResponseEntity{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + ", data=" + data + '}'; } } class OrderDetail { private String orderId; private String address; private String productId; @Override public String toString() { return "OrderDetail{" + "orderId='" + orderId + '\'' + ", address='" + address + '\'' + ", productId='" + productId + '\'' + '}'; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } }
其中,json的解析,咱們選擇了fastjson,這其實不重要。api
重要的是,你認爲,如上代碼能成功達到要求嗎???數組
無論怎麼樣,IDE 是不會報錯的,編譯也是沒問題,並且運行無誤!緩存
如上示例的輸出結果是:
result:ResponseEntity{code='1', msg='Success', data={orderid1={"address":"street 1","productId":"1342546","pay":"111.0"}}}
輸出如上結果,是由於最終 data 結構已經變成了 JsonObject 對象了,因此並無看 OrderDetail 的信息!
那麼,還有哪裏不對?不對在於,你認爲的 OrderDetail 信息,其實已經不存在了,此時,你若是直接使用 OrderDetail 的 data , 則一定致使 ClassCastException.
咱們知道,java的泛型是一種語法糖,在編譯後就會進行類型擦除。因此,在第二次泛型傳遞時,咱們已經徹底不知道其原始類型了。咱們直接來看下編譯後的代碼:
Classfile /D:/www.richCash.target.test-classes.com.test.CapitalUtilsTest.class Last modified 2019-4-6; size 1959 bytes MD5 checksum e8b36dfda241162b15ada875df4345e0 Compiled from "CapitalUtilsTest" public class com.test.CapitalUtilsTest minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #18.#42 // java.lang.Object."<init>":()V #2 = Methodref #17.#43 // com.test.CapitalUtilsTest.parseMoreGenericParams:()Lcom.test.ResponseEntity; #3 = Fieldref #44.#45 // java.lang.System.out:Ljava.io.PrintStream; #4 = Class #46 // java.lang.StringBuilder #5 = Methodref #4.#42 // java.lang.StringBuilder."<init>":()V #6 = String #47 // result: #7 = Methodref #4.#48 // java.lang.StringBuilder.append:(Ljava.lang.String;)Ljava.lang.StringBuilder; #8 = Methodref #4.#49 // java.lang.StringBuilder.append:(Ljava.lang.Object;)Ljava.lang.StringBuilder; #9 = Methodref #4.#50 // java.lang.StringBuilder.toString:()Ljava.lang.String; #10 = Methodref #51.#52 // java.io.PrintStream.println:(Ljava.lang.String;)V #11 = String #53 // {\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}} #12 = Class #54 // com.test.CapitalUtilsTest$1 #13 = Methodref #12.#55 // com.test.CapitalUtilsTest$1."<init>":(Lcom.test.CapitalUtilsTest;)V #14 = Class #56 // com.alibaba.fastjson.parser.Feature #15 = Methodref #57.#58 // com.alibaba.fastjson.JSONObject.parseObject:(Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object; #16 = Class #59 // com.test.ResponseEntity #17 = Class #60 // com.test.CapitalUtilsTest #18 = Class #61 // java.lang.Object #19 = Utf8 InnerClasses #20 = Utf8 <init> #21 = Utf8 ()V #22 = Utf8 Code #23 = Utf8 LineNumberTable #24 = Utf8 LocalVariableTable #25 = Utf8 this #26 = Utf8 Lcom.test.CapitalUtilsTest; #27 = Utf8 testInnerGenericAnalyze #28 = Utf8 result #29 = Utf8 Lcom.test.ResponseEntity; #30 = Utf8 LocalVariableTypeTable #31 = Utf8 Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;Lcom.test.OrderDetail;>;>; #32 = Utf8 RuntimeVisibleAnnotations #33 = Utf8 Lorg.junit.Test; #34 = Utf8 parseMoreGenericParams #35 = Utf8 ()Lcom.test.ResponseEntity; #36 = Utf8 json #37 = Utf8 Ljava.lang.String; #38 = Utf8 Signature #39 = Utf8 <T:Ljava.lang.Object;>()Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;TT;>;>; #40 = Utf8 SourceFile #41 = Utf8 CapitalUtilsTest #42 = NameAndType #20:#21 // "<init>":()V #43 = NameAndType #34:#35 // parseMoreGenericParams:()Lcom.test.ResponseEntity; #44 = Class #62 // java.lang.System #45 = NameAndType #63:#64 // out:Ljava.io.PrintStream; #46 = Utf8 java.lang.StringBuilder #47 = Utf8 result: #48 = NameAndType #65:#66 // append:(Ljava.lang.String;)Ljava.lang.StringBuilder; #49 = NameAndType #65:#67 // append:(Ljava.lang.Object;)Ljava.lang.StringBuilder; #50 = NameAndType #68:#69 // toString:()Ljava.lang.String; #51 = Class #70 // java.io.PrintStream #52 = NameAndType #71:#72 // println:(Ljava.lang.String;)V #53 = Utf8 {\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}} #54 = Utf8 com.test.CapitalUtilsTest$1 #55 = NameAndType #20:#73 // "<init>":(Lcom.test.CapitalUtilsTest;)V #56 = Utf8 com.alibaba.fastjson.parser.Feature #57 = Class #74 // com.alibaba.fastjson.JSONObject #58 = NameAndType #75:#76 // parseObject:(Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object; #59 = Utf8 com.test.ResponseEntity #60 = Utf8 com.test.CapitalUtilsTest #61 = Utf8 java.lang.Object #62 = Utf8 java.lang.System #63 = Utf8 out #64 = Utf8 Ljava.io.PrintStream; #65 = Utf8 append #66 = Utf8 (Ljava.lang.String;)Ljava.lang.StringBuilder; #67 = Utf8 (Ljava.lang.Object;)Ljava.lang.StringBuilder; #68 = Utf8 toString #69 = Utf8 ()Ljava.lang.String; #70 = Utf8 java.io.PrintStream #71 = Utf8 println #72 = Utf8 (Ljava.lang.String;)V #73 = Utf8 (Lcom.test.CapitalUtilsTest;)V #74 = Utf8 com.alibaba.fastjson.JSONObject #75 = Utf8 parseObject #76 = Utf8 (Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object; { public com.test.CapitalUtilsTest(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java.lang.Object."<init>":()V 4: return LineNumberTable: line 15: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom.test.CapitalUtilsTest; public void testInnerGenericAnalyze(); descriptor: ()V flags: ACC_PUBLIC Code: stack=3, locals=2, args_size=1 0: aload_0 1: invokespecial #2 // Method parseMoreGenericParams:()Lcom.test.ResponseEntity; 4: astore_1 5: getstatic #3 // Field java.lang.System.out:Ljava.io.PrintStream; 8: new #4 // class java.lang.StringBuilder 11: dup 12: invokespecial #5 // Method java.lang.StringBuilder."<init>":()V 15: ldc #6 // String result: 17: invokevirtual #7 // Method java.lang.StringBuilder.append:(Ljava.lang.String;)Ljava.lang.StringBuilder; 20: aload_1 21: invokevirtual #8 // Method java.lang.StringBuilder.append:(Ljava.lang.Object;)Ljava.lang.StringBuilder; 24: invokevirtual #9 // Method java.lang.StringBuilder.toString:()Ljava.lang.String; 27: invokevirtual #10 // Method java.io.PrintStream.println:(Ljava.lang.String;)V 30: return LineNumberTable: line 19: 0 line 20: 5 line 21: 30 LocalVariableTable: Start Length Slot Name Signature 0 31 0 this Lcom.test.CapitalUtilsTest; 5 26 1 result Lcom.test.ResponseEntity; LocalVariableTypeTable: Start Length Slot Name Signature 5 26 1 result Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;Lcom.test.OrderDetail;>;>; RuntimeVisibleAnnotations: 0: #33() private <T extends java.lang.Object> com.test.ResponseEntity<java.util.Map<java.lang.String, T>> parseMoreGenericParams(); descriptor: ()Lcom.test.ResponseEntity; flags: ACC_PRIVATE Code: stack=4, locals=2, args_size=1 0: ldc #11 // String {\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}} 2: astore_1 3: aload_1 4: new #12 // class com.test.CapitalUtilsTest$1 7: dup 8: aload_0 9: invokespecial #13 // Method com.test.CapitalUtilsTest$1."<init>":(Lcom.test.CapitalUtilsTest;)V 12: iconst_0 13: anewarray #14 // class com.alibaba.fastjson.parser.Feature 16: invokestatic #15 // Method com.alibaba.fastjson.JSONObject.parseObject:(Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object; 19: checkcast #16 // class com.test.ResponseEntity 22: areturn LineNumberTable: line 24: 0 line 25: 3 LocalVariableTable: Start Length Slot Name Signature 0 23 0 this Lcom.test.CapitalUtilsTest; 3 20 1 json Ljava.lang.String; Signature: #39 // <T:Ljava.lang.Object;>()Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;TT;>;>; } SourceFile: "CapitalUtilsTest" InnerClasses: #12; //class com.test.CapitalUtilsTest$1
很神奇,泛型竟然還在!!! 其實這隻在字節碼保留的 signature, 實際在運行時已經不在了!
因此,第二次封裝後,只剩下了object了,因此,最終解析出來的 map 的 value 會變成 jsonobject 就不足爲奇了。
這看起來很完美,好像這條路走不通了。那麼,我想轉換出內部具體類型怎麼辦?
咱們知道,fastjson 中想要解析泛型,就是經過 new TypeReference<>(){} 來實現的,那爲何它能實現,而咱們卻不能實現呢?咱們先看下 TypeReference 的泛型推斷原理吧!
package com.alibaba.fastjson; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.alibaba.fastjson.util.ParameterizedTypeImpl; import com.alibaba.fastjson.util.TypeUtils; /** * Represents a generic type {@code T}. Java doesn't yet provide a way to * represent generic types, so this class does. Forces clients to create a * subclass of this class which enables retrieval the type information even at * runtime. * * <p>For example, to create a type literal for {@code List<String>}, you can * create an empty anonymous inner class: * * <pre> * TypeReference<List<String>> list = new TypeReference<List<String>>() {}; * </pre> * This syntax cannot be used to create type literals that have wildcard * parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}. */ public class TypeReference<T> { static ConcurrentMap<Type, Type> classTypeCache = new ConcurrentHashMap<Type, Type>(16, 0.75f, 1); protected final Type type; // 通常狀況下,咱們使用此默認構造器就足夠了 /** * Constructs a new type literal. Derives represented class from type * parameter. * * <p>Clients create an empty anonymous subclass. Doing so embeds the type * parameter in the anonymous class's type hierarchy so we can reconstitute it * at runtime despite erasure. */ protected TypeReference(){ // 先獲取完整的泛型類,從這裏能夠看出,jdk的泛型雖然是擦除式的,但仍然是有跡可尋的 // TypeReference<List<String>> Type superClass = getClass().getGenericSuperclass(); // 接着,從完整的類型定義中,取出真正的泛型類型,好比 java.util.List<String> Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type cachedType = classTypeCache.get(type); if (cachedType == null) { classTypeCache.putIfAbsent(type, type); cachedType = classTypeCache.get(type); } this.type = cachedType; } /** * @since 1.2.9 * @param actualTypeArguments */ protected TypeReference(Type... actualTypeArguments){ Class<?> thisClass = this.getClass(); Type superClass = thisClass.getGenericSuperclass(); // 先直接獲取傳入 TypeReference 的泛型信息 ResponseEntity<Map<String, T>> ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0]; // 獲取無泛型類 ResponseEntity Type rawType = argType.getRawType(); // 再獲取第一層泛型信息, Map<String, T> Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0; for (int i = 0; i < argTypes.length; ++i) { // ParameterizedTypeImpl if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { argTypes[i] = actualTypeArguments[actualIndex++]; } // fix for openjdk and android env if (argTypes[i] instanceof GenericArrayType) { argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } // 若是有多層泛型且該泛型已經註明實現的狀況下,判斷該泛型下一層是否還有泛型 // 複雜類型都會被解析爲 ParameterizedType 類型 // 而相似於 T 這種泛型,則會被解析爲 TypeVariableImpl if(argTypes[i] instanceof ParameterizedType) { argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); } } // ParameterizedTypeImpl 的 hashCode() 是採用 ownerType + rawType + actualTypeArguments 進行斷定的,因此 cache 會有用 Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); Type cachedType = classTypeCache.get(key); if (cachedType == null) { classTypeCache.putIfAbsent(key, key); cachedType = classTypeCache.get(key); } // 放入緩存後返回 type = cachedType; } // ParameterizedTypeImpl.equals() @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ParameterizedTypeImpl that = (ParameterizedTypeImpl) o; // Probably incorrect - comparing Object[] arrays with Arrays.equals if (!Arrays.equals(actualTypeArguments, that.actualTypeArguments)) return false; if (ownerType != null ? !ownerType.equals(that.ownerType) : that.ownerType != null) return false; return rawType != null ? rawType.equals(that.rawType) : that.rawType == null; } // ParameterizedTypeImpl.hashCode() @Override public int hashCode() { int result = actualTypeArguments != null ? Arrays.hashCode(actualTypeArguments) : 0; result = 31 * result + (ownerType != null ? ownerType.hashCode() : 0); result = 31 * result + (rawType != null ? rawType.hashCode() : 0); return result; } // 至關於遞歸解析 private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) { Class<?> thisClass = this.getClass(); Type rawType = type.getRawType(); Type[] argTypes = type.getActualTypeArguments(); for(int i = 0; i < argTypes.length; ++i) { if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { // 經過位置一一對應。 1. 是 TypeVariable 便是 T 這樣的泛型, 如 <T1, T2, T3>, 則傳入的構造參數也應該是 (T1, T2, T3), 不然將對應錯誤 argTypes[i] = actualTypeArguments[actualIndex++]; } // fix for openjdk and android env if (argTypes[i] instanceof GenericArrayType) { argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } // 若是有多層泛型且該泛型已經註明實現的狀況下,判斷該泛型下一層是否還有泛型 // 多層則遞歸 if(argTypes[i] instanceof ParameterizedType) { return handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); } } // 從新 new 一個 ParameterizedTypeImpl 出來返回 Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); return key; } /** * Gets underlying {@code Type} instance. */ public Type getType() { return type; } // 最開始就會初始化一個 LIST_STRING 的類型備用 public final static Type LIST_STRING = new TypeReference<List<String>>() {}.getType(); }
咱們很容易想到的,就是在外部結果中,進行循環後,進行類型轉換,而後再插入到原始key中。這看起來其實也不壞,可是,你這樣反覆循環操做,是否是有點耗性能了;另外,我還得寫不少重複的代碼啊。
因此,咱們還得更優雅的方法嗎?固然你能夠不用轉,直接取jsonobject對象的值也是能夠的;
因此,更優雅的實現應該是從本質上解決問題。可是,從jdk的編譯原理上,它是作不到泛型傳遞了。那怎麼辦?既然jdk會進行類型擦除,咱們進行一次類型還原,是否是就能解決了?是的,思路如此。
具體實現,則是將具體的泛型類,以class方式傳入方法中,而後在方法進行類型還原便可!
具體咱們來看下fastjson的實現:
1. fastjson是如何解析普通泛型的?
2. fastjson是如何解析多層嵌套泛型的?
3. fastjson是如何還原泛型傳遞的?
咱們一個個來源碼:JsonObject.parseObject(); 首先對於無泛型對象,直接給出原始類就能夠了。
// com.alibaba.fastjson.JSON, 添加 DEFAULT_PARSER_FEATURE=989 /** * <pre> * String jsonStr = "[{\"id\":1001,\"name\":\"Jobs\"}]"; * List<Model> models = JSON.parseObject(jsonStr, new TypeReference<List<Model>>() {}); * </pre> * @param text json string * @param type type refernce * @param features * @return */ @SuppressWarnings("unchecked") public static <T> T parseObject(String text, TypeReference<T> type, Feature... features) { return (T) parseObject(text, type.type, ParserConfig.global, DEFAULT_PARSER_FEATURE, features); } public static <T> T parseObject(String input, Type clazz, ParserConfig config, int featureValues, Feature... features) { return parseObject(input, clazz, config, null, featureValues, features); } @SuppressWarnings("unchecked") public static <T> T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor, int featureValues, Feature... features) { // null 直接返回 null if (input == null) { return null; } // feature 默認爲空 if (features != null) { for (Feature feature : features) { featureValues |= feature.mask; } } // 使用 DefaultJSONParser 解析, 將配置參數傳入 DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues); // processor 不爲空,則添加處理邏輯 if (processor != null) { if (processor instanceof ExtraTypeProvider) { parser.getExtraTypeProviders().add((ExtraTypeProvider) processor); } if (processor instanceof ExtraProcessor) { parser.getExtraProcessors().add((ExtraProcessor) processor); } if (processor instanceof FieldTypeResolver) { parser.setFieldTypeResolver((FieldTypeResolver) processor); } } // 直接調用 DefaultJSONParser.parseObject() T value = (T) parser.parseObject(clazz, null); // 處理 value resolveTask(), parser.handleResovleTask(value); // 關閉輸出流 parser.close(); return (T) value; }
如上,就是json的的主流程,其實關鍵就在於 DefaultJSONParser 。如上操做就分幾步:
1. 分析 feature, 設置好, 關鍵是以前new 的 TypeReference 做爲類信息傳入配置;
2. 將配置項所有載入 DefaultJSONParser 中, 以備後續使用;
3. processor 配置添加;
4. 調用 DefaultJSONParser.parseObject(), 作真正的解析動做;
5. 異步 task 處理;
6. 關閉輸出流,並返回值;
因此,咱們主要來看 DefaultJSONParser 的處理邏輯;
// com.alibaba.fastjson.parser.DefaultJSONParser public DefaultJSONParser(final String input, final ParserConfig config, int features){ // 初始化 JSONScanner -> JSONLexerBase, JSONScanner 將做爲一個解析管道,順序解析結果 // 而 input 則做爲一個原始值存在 this(input, new JSONScanner(input, features), config); } public DefaultJSONParser(final Object input, final JSONLexer lexer, final ParserConfig config){ this.lexer = lexer; this.input = input; this.config = config; this.symbolTable = config.symbolTable; int ch = lexer.getCurrent(); // 根據第一個字符來斷定要解析的類型, 以 "{" 開始的是json對象, "[" 開頭的是 json 數組, 其餘的直接取下一個字符串 if (ch == '{') { lexer.next(); ((JSONLexerBase) lexer).token = JSONToken.LBRACE; } else if (ch == '[') { lexer.next(); ((JSONLexerBase) lexer).token = JSONToken.LBRACKET; } else { lexer.nextToken(); // prime the pump } } // 初始化好以後,進行關鍵的解析動做 parseObject() @SuppressWarnings("unchecked") public <T> T parseObject(Type type, Object fieldName) { // 把在構造函數中判斷出的 token 類型, 取出斷定 int token = lexer.token(); if (token == JSONToken.NULL) { lexer.nextToken(); return null; } if (token == JSONToken.LITERAL_STRING) { if (type == byte[].class) { byte[] bytes = lexer.bytesValue(); lexer.nextToken(); return (T) bytes; } if (type == char[].class) { String strVal = lexer.stringVal(); lexer.nextToken(); return (T) strVal.toCharArray(); } } // 關鍵: 獲取反序列化器, 此處的type就是 TypeReference 推斷出的 type // 實際類型爲: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl // 咱們稍後看一下是如何獲取反序列化器的 ObjectDeserializer derializer = config.getDeserializer(type); try { if (derializer.getClass() == JavaBeanDeserializer.class) { // 對於複雜類型的解析, 單獨轉換後調入, feature 爲 0 return (T) ((JavaBeanDeserializer) derializer).deserialze(this, type, fieldName, 0); } else { return (T) derializer.deserialze(this, type, fieldName); } } catch (JSONException e) { throw e; } catch (Throwable e) { throw new JSONException(e.getMessage(), e); } } // com.alibaba.fastjson.parser.ParserConfig , 獲取反序列化器 public ObjectDeserializer getDeserializer(Type type) { ObjectDeserializer derializer = this.deserializers.get(type); if (derializer != null) { return derializer; } if (type instanceof Class<?>) { return getDeserializer((Class<?>) type, type); } // 經過 TypeReference 指定類型的type 爲 ParameterizedTypeImpl, 因此會走此分支 if (type instanceof ParameterizedType) { // 會取出最外層的 泛型 class, 以決定使用哪一種 derializer Type rawType = ((ParameterizedType) type).getRawType(); if (rawType instanceof Class<?>) { // 若是外層泛型爲 class, 則進行實際泛型解析,不然遞歸操做先 return getDeserializer((Class<?>) rawType, type); } else { return getDeserializer(rawType); } } if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType) type; Type[] upperBounds = wildcardType.getUpperBounds(); if (upperBounds.length == 1) { Type upperBoundType = upperBounds[0]; return getDeserializer(upperBoundType); } } return JavaObjectDeserializer.instance; } // 多重緩存並查 public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) { ObjectDeserializer derializer = deserializers.get(type); if (derializer != null) { return derializer; } if (type == null) { type = clazz; } // 排除 type 爲空的狀況,再次查詢 derializers 緩存 derializer = deserializers.get(type); if (derializer != null) { return derializer; } { // 使用 JSONType 註釋的類處理 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class); if (annotation != null) { Class<?> mappingTo = annotation.mappingTo(); if (mappingTo != Void.class) { return getDeserializer(mappingTo, mappingTo); } } } // 直接經過主類 clazz 獲取反序列化器 if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) { derializer = deserializers.get(clazz); } if (derializer != null) { return derializer; } // 通過上面的篩選,仍然沒有值,只能新計算了 String className = clazz.getName(); className = className.replace('$', '.'); // awt 類庫特殊處理 if (className.startsWith("java.awt.") // && AwtCodec.support(clazz)) { if (!awtError) { String[] names = new String[] { "java.awt.Point", "java.awt.Font", "java.awt.Rectangle", "java.awt.Color" }; try { for (String name : names) { if (name.equals(className)) { deserializers.put(Class.forName(name), derializer = AwtCodec.instance); return derializer; } } } catch (Throwable e) { // skip awtError = true; } derializer = AwtCodec.instance; } } // jdk8 的特殊類的解析 if (!jdk8Error) { try { if (className.startsWith("java.time.")) { String[] names = new String[] { "java.time.LocalDateTime", "java.time.LocalDate", "java.time.LocalTime", "java.time.ZonedDateTime", "java.time.OffsetDateTime", "java.time.OffsetTime", "java.time.ZoneOffset", "java.time.ZoneRegion", "java.time.ZoneId", "java.time.Period", "java.time.Duration", "java.time.Instant" }; for (String name : names) { if (name.equals(className)) { deserializers.put(Class.forName(name), derializer = Jdk8DateCodec.instance); return derializer; } } } else if (className.startsWith("java.util.Optional")) { String[] names = new String[] { "java.util.Optional", "java.util.OptionalDouble", "java.util.OptionalInt", "java.util.OptionalLong" }; for (String name : names) { if (name.equals(className)) { deserializers.put(Class.forName(name), derializer = OptionalCodec.instance); return derializer; } } } } catch (Throwable e) { // skip jdk8Error = true; } } if (className.equals("java.nio.file.Path")) { deserializers.put(clazz, derializer = MiscCodec.instance); } if (clazz == Map.Entry.class) { deserializers.put(clazz, derializer = MiscCodec.instance); } final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { // 是否指定自定義的反序列化器? for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) { for (Type forType : autowired.getAutowiredFor()) { deserializers.put(forType, autowired); } } } catch (Exception ex) { // skip } if (derializer == null) { derializer = deserializers.get(type); } if (derializer != null) { return derializer; } // 各類類型依次斷定 if (clazz.isEnum()) { Class<?> deserClass = null; JSONType jsonType = clazz.getAnnotation(JSONType.class); if (jsonType != null) { deserClass = jsonType.deserializer(); try { derializer = (ObjectDeserializer) deserClass.newInstance(); deserializers.put(clazz, derializer); return derializer; } catch (Throwable error) { // skip } } derializer = new EnumDeserializer(clazz); } else if (clazz.isArray()) { derializer = ObjectArrayCodec.instance; } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) { derializer = CollectionCodec.instance; } else if (Collection.class.isAssignableFrom(clazz)) { derializer = CollectionCodec.instance; } else if (Map.class.isAssignableFrom(clazz)) { derializer = MapDeserializer.instance; } else if (Throwable.class.isAssignableFrom(clazz)) { derializer = new ThrowableDeserializer(this, clazz); } else if (PropertyProcessable.class.isAssignableFrom(clazz)) { derializer = new PropertyProcessableDeserializer((Class<PropertyProcessable>) clazz); } else if (clazz == InetAddress.class) { derializer = MiscCodec.instance; } else { // 最後,其實會落到通用的 javaBeanDesializer 上, 這個建立可不簡單,咱們稍後看一下 derializer = createJavaBeanDeserializer(clazz, type); } // 最後,將結果存入緩存,以便下一次查找 putDeserializer(type, derializer); return derializer; } // 建立一個普通 javaBeanDesializer, type 中保存有全部的原始泛型類型,泛型的推斷主要在這裏看到 public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) { boolean asmEnable = this.asmEnable & !this.fieldBased; if (asmEnable) { JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); if (jsonType != null) { Class<?> deserializerClass = jsonType.deserializer(); if (deserializerClass != Void.class) { try { Object deseralizer = deserializerClass.newInstance(); if (deseralizer instanceof ObjectDeserializer) { return (ObjectDeserializer) deseralizer; } } catch (Throwable e) { // skip } } asmEnable = jsonType.asm(); } if (asmEnable) { // 優先查看 註解上的定義 Class<?> superClass = JavaBeanInfo.getBuilderClass(clazz, jsonType); if (superClass == null) { superClass = clazz; } for (;;) { if (!Modifier.isPublic(superClass.getModifiers())) { asmEnable = false; break; } superClass = superClass.getSuperclass(); if (superClass == Object.class || superClass == null) { break; } } } } // 此處會取 T 的類型 if (clazz.getTypeParameters().length != 0) { asmEnable = false; } if (asmEnable && asmFactory != null && asmFactory.classLoader.isExternalClass(clazz)) { asmEnable = false; } if (asmEnable) { asmEnable = ASMUtils.checkName(clazz.getSimpleName()); } if (asmEnable) { if (clazz.isInterface()) { asmEnable = false; } JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy); if (asmEnable && beanInfo.fields.length > 200) { asmEnable = false; } Constructor<?> defaultConstructor = beanInfo.defaultConstructor; if (asmEnable && defaultConstructor == null && !clazz.isInterface()) { asmEnable = false; } for (FieldInfo fieldInfo : beanInfo.fields) { if (fieldInfo.getOnly) { asmEnable = false; break; } Class<?> fieldClass = fieldInfo.fieldClass; if (!Modifier.isPublic(fieldClass.getModifiers())) { asmEnable = false; break; } if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) { asmEnable = false; break; } if (fieldInfo.getMember() != null // && !ASMUtils.checkName(fieldInfo.getMember().getName())) { asmEnable = false; break; } JSONField annotation = fieldInfo.getAnnotation(); if (annotation != null // && ((!ASMUtils.checkName(annotation.name())) // || annotation.format().length() != 0 // || annotation.deserializeUsing() != Void.class // || annotation.unwrapped()) || (fieldInfo.method != null && fieldInfo.method.getParameterTypes().length > 1)) { asmEnable = false; break; } if (fieldClass.isEnum()) { // EnumDeserializer ObjectDeserializer fieldDeser = this.getDeserializer(fieldClass); if (!(fieldDeser instanceof EnumDeserializer)) { asmEnable = false; break; } } } } if (asmEnable) { if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) { asmEnable = false; } } // 總之,前面的判斷都只是爲了檢查是否可使用 asm 進行反序列化 if (!asmEnable) { // 不能則返回 JavaBeanDeserializer return new JavaBeanDeserializer(this, clazz, type); } JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy); try { return asmFactory.createJavaBeanDeserializer(this, beanInfo); // } catch (VerifyError e) { // e.printStackTrace(); // return new JavaBeanDeserializer(this, clazz, type); } catch (NoSuchMethodException ex) { return new JavaBeanDeserializer(this, clazz, type); } catch (JSONException asmError) { return new JavaBeanDeserializer(this, beanInfo); } catch (Exception e) { throw new JSONException("create asm deserializer error, " + clazz.getName(), e); } }
序列化器構造詳情
// com.alibaba.fastjson.parser.deserializerBeanDeserializer public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){ // 此處 JavaBeanInfo 的建立也是大工程啊, this(config // , JavaBeanInfo.build(clazz, type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean) ); } public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){ this.clazz = beanInfo.clazz; this.beanInfo = beanInfo; Map<String, FieldDeserializer> alterNameFieldDeserializers = null; sortedFieldDeserializers = new FieldDeserializer[beanInfo.sortedFields.length]; for (int i = 0, size = beanInfo.sortedFields.length; i < size; ++i) { FieldInfo fieldInfo = beanInfo.sortedFields[i]; FieldDeserializer fieldDeserializer = config.createFieldDeserializer(config, beanInfo, fieldInfo); sortedFieldDeserializers[i] = fieldDeserializer; for (String name : fieldInfo.alternateNames) { if (alterNameFieldDeserializers == null) { alterNameFieldDeserializers = new HashMap<String, FieldDeserializer>(); } alterNameFieldDeserializers.put(name, fieldDeserializer); } } this.alterNameFieldDeserializers = alterNameFieldDeserializers; fieldDeserializers = new FieldDeserializer[beanInfo.fields.length]; for (int i = 0, size = beanInfo.fields.length; i < size; ++i) { FieldInfo fieldInfo = beanInfo.fields[i]; // 此處會使用已排好序的 sortedFieldDeserializers 進行查找 FieldDeserializer fieldDeserializer = getFieldDeserializer(fieldInfo.name); fieldDeserializers[i] = fieldDeserializer; } } // com.alibaba.fastjson.utilBeanInfo, 幾百行的 JavaBeanInfo 的建立過程 public static JavaBeanInfo build(Class<?> clazz // , Type type // , PropertyNamingStrategy propertyNamingStrategy // , boolean fieldBased // , boolean compatibleWithJavaBean ) { JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); if (jsonType != null) { PropertyNamingStrategy jsonTypeNaming = jsonType.naming(); if (jsonTypeNaming != null && jsonTypeNaming != PropertyNamingStrategy.CamelCase) { propertyNamingStrategy = jsonTypeNaming; } } Class<?> builderClass = getBuilderClass(clazz, jsonType); // 取出字段和方法 Field[] declaredFields = clazz.getDeclaredFields(); Method[] methods = clazz.getMethods(); boolean kotlin = TypeUtils.isKotlin(clazz); Constructor[] constructors = clazz.getDeclaredConstructors(); Constructor<?> defaultConstructor = null; if ((!kotlin) || constructors.length == 1) { if (builderClass == null) { // 默認無參構造器 defaultConstructor = getDefaultConstructor(clazz, constructors); } else { defaultConstructor = getDefaultConstructor(builderClass, builderClass.getDeclaredConstructors()); } } Constructor<?> creatorConstructor = null; Method buildMethod = null; Method factoryMethod = null; List<FieldInfo> fieldList = new ArrayList<FieldInfo>(); if (fieldBased) { for (Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) { Field[] fields = currentClass.getDeclaredFields(); computeFields(clazz, type, propertyNamingStrategy, fieldList, fields); } return new JavaBeanInfo(clazz, builderClass, defaultConstructor, null, factoryMethod, buildMethod, jsonType, fieldList); } boolean isInterfaceOrAbstract = clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()); if ((defaultConstructor == null && builderClass == null) || isInterfaceOrAbstract) { creatorConstructor = getCreatorConstructor(constructors); if (creatorConstructor != null && !isInterfaceOrAbstract) { // 基於標記 JSONCreator 註解的構造方法 TypeUtils.setAccessible(creatorConstructor); Class<?>[] types = creatorConstructor.getParameterTypes(); String[] lookupParameterNames = null; if (types.length > 0) { Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); for (int i = 0; i < types.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; JSONField fieldAnnotation = null; for (Annotation paramAnnotation : paramAnnotations) { if (paramAnnotation instanceof JSONField) { fieldAnnotation = (JSONField) paramAnnotation; break; } } Class<?> fieldClass = types[i]; Type fieldType = creatorConstructor.getGenericParameterTypes()[i]; String fieldName = null; Field field = null; int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; if (fieldAnnotation != null) { field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields); ordinal = fieldAnnotation.ordinal(); serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); fieldName = fieldAnnotation.name(); } if (fieldName == null || fieldName.length() == 0) { if (lookupParameterNames == null) { lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor); } fieldName = lookupParameterNames[i]; } FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures); add(fieldList, fieldInfo); } } //return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList); } else if ((factoryMethod = getFactoryMethod(clazz, methods)) != null) { TypeUtils.setAccessible(factoryMethod); Class<?>[] types = factoryMethod.getParameterTypes(); if (types.length > 0) { Annotation[][] paramAnnotationArrays = factoryMethod.getParameterAnnotations(); for (int i = 0; i < types.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; JSONField fieldAnnotation = null; for (Annotation paramAnnotation : paramAnnotations) { if (paramAnnotation instanceof JSONField) { fieldAnnotation = (JSONField) paramAnnotation; break; } } if (fieldAnnotation == null) { throw new JSONException("illegal json creator"); } Class<?> fieldClass = types[i]; Type fieldType = factoryMethod.getGenericParameterTypes()[i]; Field field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields); final int ordinal = fieldAnnotation.ordinal(); final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); final int parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures); add(fieldList, fieldInfo); } return new JavaBeanInfo(clazz, builderClass, null, null, factoryMethod, null, jsonType, fieldList); } } else if (!isInterfaceOrAbstract) { String className = clazz.getName(); String[] paramNames = null; if (kotlin && constructors.length > 0) { paramNames = TypeUtils.getKoltinConstructorParameters(clazz); creatorConstructor = TypeUtils.getKoltinConstructor(constructors, paramNames); TypeUtils.setAccessible(creatorConstructor); } else { for (Constructor constructor : constructors) { Class<?>[] parameterTypes = constructor.getParameterTypes(); if (className.equals("org.springframework.security.web.authentication.WebAuthenticationDetails")) { if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) { creatorConstructor = constructor; creatorConstructor.setAccessible(true); paramNames = ASMUtils.lookupParameterNames(constructor); break; } } if (className.equals("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken")) { if (parameterTypes.length == 3 && parameterTypes[0] == Object.class && parameterTypes[1] == Object.class && parameterTypes[2] == Collection.class) { creatorConstructor = constructor; creatorConstructor.setAccessible(true); paramNames = new String[] {"principal", "credentials", "authorities"}; break; } } if (className.equals("org.springframework.security.core.authority.SimpleGrantedAuthority")) { if (parameterTypes.length == 1 && parameterTypes[0] == String.class) { creatorConstructor = constructor; paramNames = new String[] {"authority"}; break; } } // boolean is_public = (constructor.getModifiers() & Modifier.PUBLIC) != 0; if (!is_public) { continue; } String[] lookupParameterNames = ASMUtils.lookupParameterNames(constructor); if (lookupParameterNames == null || lookupParameterNames.length == 0) { continue; } if (creatorConstructor != null && paramNames != null && lookupParameterNames.length <= paramNames.length) { continue; } paramNames = lookupParameterNames; creatorConstructor = constructor; } } Class<?>[] types = null; if (paramNames != null) { types = creatorConstructor.getParameterTypes(); } if (paramNames != null && types.length == paramNames.length) { Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); for (int i = 0; i < types.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; String paramName = paramNames[i]; JSONField fieldAnnotation = null; for (Annotation paramAnnotation : paramAnnotations) { if (paramAnnotation instanceof JSONField) { fieldAnnotation = (JSONField) paramAnnotation; break; } } Class<?> fieldClass = types[i]; Type fieldType = creatorConstructor.getGenericParameterTypes()[i]; Field field = TypeUtils.getField(clazz, paramName, declaredFields); if (field != null) { if (fieldAnnotation == null) { fieldAnnotation = field.getAnnotation(JSONField.class); } } final int ordinal, serialzeFeatures, parserFeatures; if (fieldAnnotation == null) { ordinal = 0; serialzeFeatures = 0; if ("org.springframework.security.core.userdetails.User".equals(className) && "password".equals(paramName)) { parserFeatures = Feature.InitStringFieldAsEmpty.mask; } else { parserFeatures = 0; } } else { String nameAnnotated = fieldAnnotation.name(); if (nameAnnotated.length() != 0) { paramName = nameAnnotated; } ordinal = fieldAnnotation.ordinal(); serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); } FieldInfo fieldInfo = new FieldInfo(paramName, clazz, fieldClass, fieldType, field, ordinal, serialzeFeatures, parserFeatures); add(fieldList, fieldInfo); } if ((!kotlin) && !clazz.getName().equals("javax.servlet.http.Cookie")) { return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList); } } else { throw new JSONException("default constructor not found. " + clazz); } } } if (defaultConstructor != null) { TypeUtils.setAccessible(defaultConstructor); } if (builderClass != null) { String withPrefix = null; JSONPOJOBuilder builderAnno = builderClass.getAnnotation(JSONPOJOBuilder.class); if (builderAnno != null) { withPrefix = builderAnno.withPrefix(); } if (withPrefix == null || withPrefix.length() == 0) { withPrefix = "with"; } for (Method method : builderClass.getMethods()) { if (Modifier.isStatic(method.getModifiers())) { continue; } if (!(method.getReturnType().equals(builderClass))) { continue; } int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; JSONField annotation = method.getAnnotation(JSONField.class); if (annotation == null) { annotation = TypeUtils.getSuperMethodAnnotation(clazz, method); } if (annotation != null) { if (!annotation.deserialize()) { continue; } ordinal = annotation.ordinal(); serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures()); parserFeatures = Feature.of(annotation.parseFeatures()); if (annotation.name().length() != 0) { String propertyName = annotation.name(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null)); continue; } } String methodName = method.getName(); StringBuilder properNameBuilder; if (methodName.startsWith("set") && methodName.length() > 3) { properNameBuilder = new StringBuilder(methodName.substring(3)); } else { if (!methodName.startsWith(withPrefix)) { continue; } if (methodName.length() <= withPrefix.length()) { continue; } properNameBuilder = new StringBuilder(methodName.substring(withPrefix.length())); } char c0 = properNameBuilder.charAt(0); if (!Character.isUpperCase(c0)) { continue; } properNameBuilder.setCharAt(0, Character.toLowerCase(c0)); String propertyName = properNameBuilder.toString(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null)); } if (builderClass != null) { JSONPOJOBuilder builderAnnotation = builderClass.getAnnotation(JSONPOJOBuilder.class); String buildMethodName = null; if (builderAnnotation != null) { buildMethodName = builderAnnotation.buildMethod(); } if (buildMethodName == null || buildMethodName.length() == 0) { buildMethodName = "build"; } try { buildMethod = builderClass.getMethod(buildMethodName); } catch (NoSuchMethodException e) { // skip } catch (SecurityException e) { // skip } if (buildMethod == null) { try { buildMethod = builderClass.getMethod("create"); } catch (NoSuchMethodException e) { // skip } catch (SecurityException e) { // skip } } if (buildMethod == null) { throw new JSONException("buildMethod not found."); } TypeUtils.setAccessible(buildMethod); } } for (Method method : methods) { // int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; String methodName = method.getName(); if (Modifier.isStatic(method.getModifiers())) { continue; } // support builder set Class<?> returnType = method.getReturnType(); if (!(returnType.equals(Void.TYPE) || returnType.equals(method.getDeclaringClass()))) { continue; } if (method.getDeclaringClass() == Object.class) { continue; } Class<?>[] types = method.getParameterTypes(); if (types.length == 0 || types.length > 2) { continue; } JSONField annotation = method.getAnnotation(JSONField.class); if (annotation != null && types.length == 2 && types[0] == String.class && types[1] == Object.class) { add(fieldList, new FieldInfo("", method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null)); continue; } if (types.length != 1) { continue; } if (annotation == null) { annotation = TypeUtils.getSuperMethodAnnotation(clazz, method); } if (annotation == null && methodName.length() < 4) { continue; } if (annotation != null) { if (!annotation.deserialize()) { continue; } ordinal = annotation.ordinal(); serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures()); parserFeatures = Feature.of(annotation.parseFeatures()); if (annotation.name().length() != 0) { String propertyName = annotation.name(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, null, null)); continue; } } if (annotation == null && !methodName.startsWith("set")) { // TODO "set"的判斷放在 JSONField 註解後面,意思是容許非 setter 方法標記 JSONField 註解? continue; } char c3 = methodName.charAt(3); String propertyName; if (Character.isUpperCase(c3) // || c3 > 512 // for unicode method name ) { if (TypeUtils.compatibleWithJavaBean) { propertyName = TypeUtils.decapitalize(methodName.substring(3)); } else { propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); } } else if (c3 == '_') { propertyName = methodName.substring(4); } else if (c3 == 'f') { propertyName = methodName.substring(3); } else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) { propertyName = TypeUtils.decapitalize(methodName.substring(3)); } else { continue; } Field field = TypeUtils.getField(clazz, propertyName, declaredFields); if (field == null && types[0] == boolean.class) { String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1); field = TypeUtils.getField(clazz, isFieldName, declaredFields); } JSONField fieldAnnotation = null; if (field != null) { fieldAnnotation = field.getAnnotation(JSONField.class); if (fieldAnnotation != null) { if (!fieldAnnotation.deserialize()) { continue; } ordinal = fieldAnnotation.ordinal(); serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); if (fieldAnnotation.name().length() != 0) { propertyName = fieldAnnotation.name(); add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null)); continue; } } } if (propertyNamingStrategy != null) { propertyName = propertyNamingStrategy.translate(propertyName); } // 添加解析出的字段到 fieldList 中 add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null)); } // 由於在上面加入了一些字段,因此如今從新取字段 Field[] fields = clazz.getFields(); computeFields(clazz, type, propertyNamingStrategy, fieldList, fields); for (Method method : clazz.getMethods()) { // getter methods String methodName = method.getName(); if (methodName.length() < 4) { continue; } if (Modifier.isStatic(method.getModifiers())) { continue; } if (builderClass == null && methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3))) { if (method.getParameterTypes().length != 0) { continue; } if (Collection.class.isAssignableFrom(method.getReturnType()) // || Map.class.isAssignableFrom(method.getReturnType()) // || AtomicBoolean.class == method.getReturnType() // || AtomicInteger.class == method.getReturnType() // || AtomicLong.class == method.getReturnType() // ) { String propertyName; JSONField annotation = method.getAnnotation(JSONField.class); if (annotation != null && annotation.deserialize()) { continue; } if (annotation != null && annotation.name().length() > 0) { propertyName = annotation.name(); } else { propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); Field field = TypeUtils.getField(clazz, propertyName, declaredFields); if (field != null) { JSONField fieldAnnotation = field.getAnnotation(JSONField.class); if (fieldAnnotation != null && !fieldAnnotation.deserialize()) { continue; } } } if (propertyNamingStrategy != null) { propertyName = propertyNamingStrategy.translate(propertyName); } FieldInfo fieldInfo = getField(fieldList, propertyName); if (fieldInfo != null) { continue; } add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, 0, 0, 0, annotation, null, null)); } } } // 最後返回 JavaBeanInfo return new JavaBeanInfo(clazz, builderClass, defaultConstructor, creatorConstructor, factoryMethod, buildMethod, jsonType, fieldList); }
序列化構造器詳情2:
// com.alibaba.fastjson.util.FieldInfo , 構建字段信息 public FieldInfo(String name, // Method method, // Field field, // Class<?> clazz, // Type type, // int ordinal, // int serialzeFeatures, // int parserFeatures, // JSONField fieldAnnotation, // JSONField methodAnnotation, // String label){ if (field != null) { String fieldName = field.getName(); if (fieldName.equals(name)) { name = fieldName; } } if (ordinal < 0) { ordinal = 0; } this.name = name; this.method = method; this.field = field; this.ordinal = ordinal; this.serialzeFeatures = serialzeFeatures; this.parserFeatures = parserFeatures; this.fieldAnnotation = fieldAnnotation; this.methodAnnotation = methodAnnotation; if (field != null) { int modifiers = field.getModifiers(); fieldAccess = ((modifiers & Modifier.PUBLIC) != 0 || method == null); fieldTransient = Modifier.isTransient(modifiers) || TypeUtils.isTransient(method); } else { fieldAccess = false; fieldTransient = false; } if (label != null && label.length() > 0) { this.label = label; } else { this.label = ""; } String format = null; JSONField annotation = getAnnotation(); boolean jsonDirect = false; if (annotation != null) { format = annotation.format(); if (format.trim().length() == 0) { format = null; } jsonDirect = annotation.jsonDirect(); unwrapped = annotation.unwrapped(); alternateNames = annotation.alternateNames(); } else { jsonDirect = false; unwrapped = false; alternateNames = new String[0]; } this.format = format; name_chars = genFieldNameChars(); if (method != null) { TypeUtils.setAccessible(method); } if (field != null) { TypeUtils.setAccessible(field); } boolean getOnly = false; Type fieldType; Class<?> fieldClass; if (method != null) { Class<?>[] types; if ((types = method.getParameterTypes()).length == 1) { // 泛型在此變爲 java.lang.Object // 因此,泛型的推斷關鍵,就交給了 type 字段的設值了 fieldClass = types[0]; // 泛型可推斷出值, 如題中 Map<String, T>, 此處將得出 T 的 TypeVariableImpl , 可是 fieldClass = java.lang.Object fieldType = method.getGenericParameterTypes()[0]; } else if (types.length == 2 && types[0] == String.class && types[1] == Object.class) { fieldType = fieldClass = types[0]; } else { fieldClass = method.getReturnType(); fieldType = method.getGenericReturnType(); getOnly = true; } this.declaringClass = method.getDeclaringClass(); } else { fieldClass = field.getType(); fieldType = field.getGenericType(); this.declaringClass = field.getDeclaringClass(); getOnly = Modifier.isFinal(field.getModifiers()); } this.getOnly = getOnly; this.jsonDirect = jsonDirect && fieldClass == String.class; if (clazz != null && fieldClass == Object.class && fieldType instanceof TypeVariable) { TypeVariable<?> tv = (TypeVariable<?>) fieldType; // 再次經過原始指定的泛型進行一次推斷,獲得泛型的真正類,從而達到還原泛型的目的 // 泛型的繼承關係推斷 Type genericFieldType = getInheritGenericType(clazz, type, tv); if (genericFieldType != null) { this.fieldClass = TypeUtils.getClass(genericFieldType); this.fieldType = genericFieldType; isEnum = fieldClass.isEnum(); return; } } Type genericFieldType = fieldType; if (!(fieldType instanceof Class)) { genericFieldType = getFieldType(clazz, type != null ? type : clazz, fieldType); if (genericFieldType != fieldType) { if (genericFieldType instanceof ParameterizedType) { fieldClass = TypeUtils.getClass(genericFieldType); } else if (genericFieldType instanceof Class) { fieldClass = TypeUtils.getClass(genericFieldType); } } } this.fieldType = genericFieldType; this.fieldClass = fieldClass; isEnum = fieldClass.isEnum(); } private static Type getInheritGenericType(Class<?> clazz, Type type, TypeVariable<?> tv) { GenericDeclaration gd = tv.getGenericDeclaration(); Class<?> class_gd = null; if (gd instanceof Class) { class_gd = (Class<?>) tv.getGenericDeclaration(); } Type[] arguments = null; if (class_gd == clazz) { // 泛型的還原都是經過 ParameterizedType 來實現的 // 此處會一層層還原,如題的操做第一層還原將獲得 java.util.Map<String, T> // 因此,泛型的推斷關鍵,就交給了 type 字段的設值了 if (type instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) type; // 設置的泛型會在此處進行體現 arguments = ptype.getActualTypeArguments(); } } else { for (Class<?> c = clazz; c != null && c != Object.class && c != class_gd; c = c.getSuperclass()) { Type superType = c.getGenericSuperclass(); if (superType instanceof ParameterizedType) { ParameterizedType p_superType = (ParameterizedType) superType; Type[] p_superType_args = p_superType.getActualTypeArguments(); getArgument(p_superType_args, c.getTypeParameters(), arguments); arguments = p_superType_args; } } } if (arguments == null || class_gd == null) { return null; } Type actualType = null; // 此處將會獲取到泛型 T, 與 將 tv 與 typeVariables 進行比較,若是找到設置值則,得出泛型的原型,以待後用 TypeVariable<?>[] typeVariables = class_gd.getTypeParameters(); for (int j = 0; j < typeVariables.length; ++j) { // 最終的泛型結果,在查找中獲得 if (tv.equals(typeVariables[j])) { actualType = arguments[j]; break; } } // Map<String, T> return actualType; } private static Type getInheritGenericType(Class<?> clazz, Type type, TypeVariable<?> tv) { GenericDeclaration gd = tv.getGenericDeclaration(); Class<?> class_gd = null; if (gd instanceof Class) { class_gd = (Class<?>) tv.getGenericDeclaration(); } Type[] arguments = null; if (class_gd == clazz) { if (type instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) type; arguments = ptype.getActualTypeArguments(); } } else { for (Class<?> c = clazz; c != null && c != Object.class && c != class_gd; c = c.getSuperclass()) { Type superType = c.getGenericSuperclass(); if (superType instanceof ParameterizedType) { ParameterizedType p_superType = (ParameterizedType) superType; Type[] p_superType_args = p_superType.getActualTypeArguments(); getArgument(p_superType_args, c.getTypeParameters(), arguments); arguments = p_superType_args; } } } if (arguments == null || class_gd == null) { return null; } Type actualType = null; TypeVariable<?>[] typeVariables = class_gd.getTypeParameters(); for (int j = 0; j < typeVariables.length; ++j) { if (tv.equals(typeVariables[j])) { actualType = arguments[j]; break; } } return actualType; } // 參數配置好後,new JavaBeanInfo() public JavaBeanInfo(Class<?> clazz, // Class<?> builderClass, // Constructor<?> defaultConstructor, // Constructor<?> creatorConstructor, // Method factoryMethod, // Method buildMethod, // JSONType jsonType, // List<FieldInfo> fieldList) { this.clazz = clazz; this.builderClass = builderClass; this.defaultConstructor = defaultConstructor; this.creatorConstructor = creatorConstructor; this.factoryMethod = factoryMethod; this.parserFeatures = TypeUtils.getParserFeatures(clazz); this.buildMethod = buildMethod; this.jsonType = jsonType; if (jsonType != null) { String typeName = jsonType.typeName(); String typeKey = jsonType.typeKey(); this.typeKey = typeKey.length() > 0 ? typeKey : null; if (typeName.length() != 0) { this.typeName = typeName; } else { this.typeName = clazz.getName(); } String[] orders = jsonType.orders(); this.orders = orders.length == 0 ? null : orders; } else { this.typeName = clazz.getName(); this.typeKey = null; this.orders = null; } // 字段信息 fields = new FieldInfo[fieldList.size()]; fieldList.toArray(fields); FieldInfo[] sortedFields = new FieldInfo[fields.length]; if (orders != null) { LinkedHashMap<String, FieldInfo> map = new LinkedHashMap<String, FieldInfo>(fieldList.size()); for (FieldInfo field : fields) { map.put(field.name, field); } int i = 0; for (String item : orders) { FieldInfo field = map.get(item); if (field != null) { sortedFields[i++] = field; map.remove(item); } } for (FieldInfo field : map.values()) { sortedFields[i++] = field; } } else { System.arraycopy(fields, 0, sortedFields, 0, fields.length); Arrays.sort(sortedFields); } if (Arrays.equals(fields, sortedFields)) { sortedFields = fields; } this.sortedFields = sortedFields; if (defaultConstructor != null) { defaultConstructorParameterSize = defaultConstructor.getParameterTypes().length; } else if (factoryMethod != null) { defaultConstructorParameterSize = factoryMethod.getParameterTypes().length; } else { defaultConstructorParameterSize = 0; } if (creatorConstructor != null) { this.creatorConstructorParameterTypes = creatorConstructor.getParameterTypes(); kotlin = TypeUtils.isKotlin(clazz); if (kotlin) { this.creatorConstructorParameters = TypeUtils.getKoltinConstructorParameters(clazz); try { this.kotlinDefaultConstructor = clazz.getConstructor(); } catch (Throwable ex) { // skip } Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations(); for (int i = 0; i < creatorConstructorParameters.length && i < paramAnnotationArrays.length; ++i) { Annotation[] paramAnnotations = paramAnnotationArrays[i]; JSONField fieldAnnotation = null; for (Annotation paramAnnotation : paramAnnotations) { if (paramAnnotation instanceof JSONField) { fieldAnnotation = (JSONField) paramAnnotation; break; } } if (fieldAnnotation != null) { String fieldAnnotationName = fieldAnnotation.name(); if (fieldAnnotationName.length() > 0) { creatorConstructorParameters[i] = fieldAnnotationName; } } } } else { boolean match; if (creatorConstructorParameterTypes.length != fields.length) { match = false; } else { match = true; for (int i = 0; i < creatorConstructorParameterTypes.length; i++) { if (creatorConstructorParameterTypes[i] != fields[i].fieldClass) { match = false; break; } } } if (!match) { this.creatorConstructorParameters = ASMUtils.lookupParameterNames(creatorConstructor); } } } } // com.alibaba.fastjson.parser.deserializerBeanDeserializer public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){ this(config // , JavaBeanInfo.build(clazz, type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean) ); } public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){ this.clazz = beanInfo.clazz; this.beanInfo = beanInfo; Map<String, FieldDeserializer> alterNameFieldDeserializers = null; sortedFieldDeserializers = new FieldDeserializer[beanInfo.sortedFields.length]; for (int i = 0, size = beanInfo.sortedFields.length; i < size; ++i) { // 將前端解析出的字段配置取出, 爲每一個字段建立一個解析器 FieldInfo fieldInfo = beanInfo.sortedFields[i]; FieldDeserializer fieldDeserializer = config.createFieldDeserializer(config, beanInfo, fieldInfo); // 將對應的反序列化器放入到對應的位置 sortedFieldDeserializers[i] = fieldDeserializer; for (String name : fieldInfo.alternateNames) { if (alterNameFieldDeserializers == null) { alterNameFieldDeserializers = new HashMap<String, FieldDeserializer>(); } alterNameFieldDeserializers.put(name, fieldDeserializer); } } this.alterNameFieldDeserializers = alterNameFieldDeserializers; fieldDeserializers = new FieldDeserializer[beanInfo.fields.length]; for (int i = 0, size = beanInfo.fields.length; i < size; ++i) { FieldInfo fieldInfo = beanInfo.fields[i]; // 根據 key 查找序列化器, 使用二分查找法 FieldDeserializer fieldDeserializer = getFieldDeserializer(fieldInfo.name); fieldDeserializers[i] = fieldDeserializer; } } // com.alibaba.fastjson.parser.ParserConfig public FieldDeserializer createFieldDeserializer(ParserConfig mapping, // JavaBeanInfo beanInfo, // FieldInfo fieldInfo) { Class<?> clazz = beanInfo.clazz; Class<?> fieldClass = fieldInfo.fieldClass; Class<?> deserializeUsing = null; JSONField annotation = fieldInfo.getAnnotation(); if (annotation != null) { deserializeUsing = annotation.deserializeUsing(); if (deserializeUsing == Void.class) { deserializeUsing = null; } } if (deserializeUsing == null && (fieldClass == List.class || fieldClass == ArrayList.class)) { return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo); } return new DefaultFieldDeserializer(mapping, clazz, fieldInfo); } public FieldDeserializer getFieldDeserializer(String key) { return getFieldDeserializer(key, null); } public FieldDeserializer getFieldDeserializer(String key, int[] setFlags) { if (key == null) { return null; } int low = 0; int high = sortedFieldDeserializers.length - 1; while (low <= high) { int mid = (low + high) >>> 1; String fieldName = sortedFieldDeserializers[mid].fieldInfo.name; int cmp = fieldName.compareTo(key); if (cmp < 0) { low = mid + 1; } else if (cmp > 0) { high = mid - 1; } else { if (isSetFlag(mid, setFlags)) { return null; } return sortedFieldDeserializers[mid]; // key found } } if(this.alterNameFieldDeserializers != null){ return this.alterNameFieldDeserializers.get(key); } return null; // key not found. }
解析
// 獲取到 Serializer 後,就進行 derialize() 處理了! // 流程以下 // com.alibaba.fastjson.parser.deserializerBeanDeserializer public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName, int features) { return deserialze(parser, type, fieldName, null, features, null); } // 一長串的解析動做 @SuppressWarnings({ "unchecked", "rawtypes" }) protected <T> T deserialze(DefaultJSONParser parser, // Type type, // Object fieldName, // Object object, // int features, // int[] setFlags) { if (type == JSON.class || type == JSONObject.class) { return (T) parser.parse(); } // 獲取配置, parser 爲 DefaultJSONParser final JSONLexerBase lexer = (JSONLexerBase) parser.lexer; // xxx final ParserConfig config = parser.getConfig(); int token = lexer.token(); if (token == JSONToken.NULL) { lexer.nextToken(JSONToken.COMMA); return null; } ParseContext context = parser.getContext(); if (object != null && context != null) { context = context.parent; } ParseContext childContext = null; try { Map<String, Object> fieldValues = null; if (token == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); if (object == null) { object = createInstance(parser, type); } return (T) object; } if (token == JSONToken.LBRACKET) { final int mask = Feature.SupportArrayToBean.mask; boolean isSupportArrayToBean = (beanInfo.parserFeatures & mask) != 0 // || lexer.isEnabled(Feature.SupportArrayToBean) // || (features & mask) != 0 ; if (isSupportArrayToBean) { return deserialzeArrayMapping(parser, type, fieldName, object); } } if (token != JSONToken.LBRACE && token != JSONToken.COMMA) { if (lexer.isBlankInput()) { return null; } if (token == JSONToken.LITERAL_STRING) { String strVal = lexer.stringVal(); if (strVal.length() == 0) { lexer.nextToken(); return null; } if (beanInfo.jsonType != null) { for (Class<?> seeAlsoClass : beanInfo.jsonType.seeAlso()) { if (Enum.class.isAssignableFrom(seeAlsoClass)) { try { Enum<?> e = Enum.valueOf((Class<Enum>) seeAlsoClass, strVal); return (T) e; } catch (IllegalArgumentException e) { // skip } } } } } else if (token == JSONToken.LITERAL_ISO8601_DATE) { Calendar calendar = lexer.getCalendar(); } if (token == JSONToken.LBRACKET && lexer.getCurrent() == ']') { lexer.next(); lexer.nextToken(); return null; } StringBuilder buf = (new StringBuilder()) // .append("syntax error, expect {, actual ") // .append(lexer.tokenName()) // .append(", pos ") // .append(lexer.pos()); if (fieldName instanceof String) { buf // .append(", fieldName ") // .append(fieldName); } buf.append(", fastjson-version ").append(JSON.VERSION); throw new JSONException(buf.toString()); } if (parser.resolveStatus == DefaultJSONParser.TypeNameRedirect) { parser.resolveStatus = DefaultJSONParser.NONE; } // 解析單個 field String typeKey = beanInfo.typeKey; for (int fieldIndex = 0;; fieldIndex++) { String key = null; FieldDeserializer fieldDeser = null; FieldInfo fieldInfo = null; Class<?> fieldClass = null; JSONField feildAnnotation = null; boolean customDeserilizer = false; if (fieldIndex < sortedFieldDeserializers.length) { fieldDeser = sortedFieldDeserializers[fieldIndex]; fieldInfo = fieldDeser.fieldInfo; fieldClass = fieldInfo.fieldClass; feildAnnotation = fieldInfo.getAnnotation(); if (feildAnnotation != null && fieldDeser instanceof DefaultFieldDeserializer) { customDeserilizer = ((DefaultFieldDeserializer) fieldDeser).customDeserilizer; } } boolean matchField = false; boolean valueParsed = false; // 先根據類型,解析出各字段的字段名 Object fieldValue = null; if (fieldDeser != null) { char[] name_chars = fieldInfo.name_chars; if (customDeserilizer && lexer.matchField(name_chars)) { matchField = true; } else if (fieldClass == int.class || fieldClass == Integer.class) { int intVal = lexer.scanFieldInt(name_chars); if (intVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { fieldValue = null; } else { fieldValue = intVal; } if (lexer.matchStat > 0) { matchField = true; valueParsed = true; // 若是找不到匹配信息,則跳過就好 } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == long.class || fieldClass == Long.class) { long longVal = lexer.scanFieldLong(name_chars); if (longVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { fieldValue = null; } else { fieldValue = longVal; } if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == String.class) { // String 類型直接獲取, "code" 字段獲取 fieldValue = lexer.scanFieldString(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == java.util.Date.class && fieldInfo.format == null) { fieldValue = lexer.scanFieldDate(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == BigDecimal.class) { fieldValue = lexer.scanFieldDecimal(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == BigInteger.class) { fieldValue = lexer.scanFieldBigInteger(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == boolean.class || fieldClass == Boolean.class) { boolean booleanVal = lexer.scanFieldBoolean(name_chars); if (lexer.matchStat == JSONLexer.VALUE_NULL) { fieldValue = null; } else { fieldValue = booleanVal; } if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == float.class || fieldClass == Float.class) { float floatVal = lexer.scanFieldFloat(name_chars); if (floatVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { fieldValue = null; } else { fieldValue = floatVal; } if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == double.class || fieldClass == Double.class) { double doubleVal = lexer.scanFieldDouble(name_chars); if (doubleVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) { fieldValue = null; } else { fieldValue = doubleVal; } if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass.isEnum() // && parser.getConfig().getDeserializer(fieldClass) instanceof EnumDeserializer && (feildAnnotation == null || feildAnnotation.deserializeUsing() == Void.class) ) { if (fieldDeser instanceof DefaultFieldDeserializer) { ObjectDeserializer fieldValueDeserilizer = ((DefaultFieldDeserializer) fieldDeser).fieldValueDeserilizer; fieldValue = this.scanEnum(lexer, name_chars, fieldValueDeserilizer); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } } else if (fieldClass == int[].class) { fieldValue = lexer.scanFieldIntArray(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == float[].class) { fieldValue = lexer.scanFieldFloatArray(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (fieldClass == float[][].class) { fieldValue = lexer.scanFieldFloatArray2(name_chars); if (lexer.matchStat > 0) { matchField = true; valueParsed = true; } else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) { continue; } } else if (lexer.matchField(name_chars)) { matchField = true; } else { continue; } } if (!matchField) { // 對於複雜泛型的解析,將從 symbolTable 中獲取,該 symbolTable 中會以 orderId, name ... 形式呈現 key = lexer.scanSymbol(parser.symbolTable); if (key == null) { token = lexer.token(); if (token == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); break; } if (token == JSONToken.COMMA) { if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { continue; } } } if ("$ref" == key && context != null) { lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); token = lexer.token(); if (token == JSONToken.LITERAL_STRING) { String ref = lexer.stringVal(); if ("@".equals(ref)) { object = context.object; } else if ("..".equals(ref)) { ParseContext parentContext = context.parent; if (parentContext.object != null) { object = parentContext.object; } else { parser.addResolveTask(new ResolveTask(parentContext, ref)); parser.resolveStatus = DefaultJSONParser.NeedToResolve; } } else if ("$".equals(ref)) { ParseContext rootContext = context; while (rootContext.parent != null) { rootContext = rootContext.parent; } if (rootContext.object != null) { object = rootContext.object; } else { parser.addResolveTask(new ResolveTask(rootContext, ref)); parser.resolveStatus = DefaultJSONParser.NeedToResolve; } } else { if (ref.indexOf('\\') > 0) { StringBuilder buf = new StringBuilder(); for (int i = 0; i < ref.length(); ++i) { char ch = ref.charAt(i); if (ch == '\\') { ch = ref.charAt(++i); } buf.append(ch); } ref = buf.toString(); } Object refObj = parser.resolveReference(ref); if (refObj != null) { object = refObj; } else { parser.addResolveTask(new ResolveTask(context, ref)); parser.resolveStatus = DefaultJSONParser.NeedToResolve; } } } else { throw new JSONException("illegal ref, " + JSONToken.name(token)); } lexer.nextToken(JSONToken.RBRACE); if (lexer.token() != JSONToken.RBRACE) { throw new JSONException("illegal ref"); } lexer.nextToken(JSONToken.COMMA); parser.setContext(context, object, fieldName); return (T) object; } if ((typeKey != null && typeKey.equals(key)) || JSON.DEFAULT_TYPE_KEY == key) { lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); if (lexer.token() == JSONToken.LITERAL_STRING) { String typeName = lexer.stringVal(); lexer.nextToken(JSONToken.COMMA); if (typeName.equals(beanInfo.typeName)|| parser.isEnabled(Feature.IgnoreAutoType)) { if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(); break; } continue; } ObjectDeserializer deserializer = getSeeAlso(config, this.beanInfo, typeName); Class<?> userType = null; if (deserializer == null) { Class<?> expectClass = TypeUtils.getClass(type); userType = config.checkAutoType(typeName, expectClass, lexer.getFeatures()); deserializer = parser.getConfig().getDeserializer(userType); } Object typedObject = deserializer.deserialze(parser, userType, fieldName); if (deserializer instanceof JavaBeanDeserializer) { JavaBeanDeserializer javaBeanDeserializer = (JavaBeanDeserializer) deserializer; if (typeKey != null) { FieldDeserializer typeKeyFieldDeser = javaBeanDeserializer.getFieldDeserializer(typeKey); typeKeyFieldDeser.setValue(typedObject, typeName); } } return (T) typedObject; } else { throw new JSONException("syntax error"); } } } if (object == null && fieldValues == null) { // 按照以前解析好的構造器,初始化一個實例,並做爲返回的依據 // 找不到類型,則建立 HashMap, 因此 HashMap 是兜底數據結構 object = createInstance(parser, type); if (object == null) { fieldValues = new HashMap<String, Object>(this.fieldDeserializers.length); } childContext = parser.setContext(context, object, fieldName); if (setFlags == null) { // 32位一個標記位 setFlags = new int[(this.fieldDeserializers.length / 32) + 1]; } } // 找到匹配後,解析 if (matchField) { if (!valueParsed) { fieldDeser.parseField(parser, object, type, fieldValues); } else { if (object == null) { fieldValues.put(fieldInfo.name, fieldValue); } else if (fieldValue == null) { if (fieldClass != int.class // && fieldClass != long.class // && fieldClass != float.class // && fieldClass != double.class // && fieldClass != boolean.class // ) { fieldDeser.setValue(object, fieldValue); } } else { // 將解析出的值放入到 fieldDeser // 使用反射寫入 method.invoke(obj, value) // fieldDeser 是對象的 一個字段描述 fieldDeser.setValue(object, fieldValue); } if (setFlags != null) { int flagIndex = fieldIndex / 32; int bitIndex = fieldIndex % 32; setFlags[flagIndex] |= (1 >> bitIndex); } if (lexer.matchStat == JSONLexer.END) { break; } } } else { // 若是沒有匹配的話,就走字段解析,即遞歸操做 boolean match = parseField(parser, key, object, type, fieldValues, setFlags); if (!match) { if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(); break; } continue; } else if (lexer.token() == JSONToken.COLON) { throw new JSONException("syntax error, unexpect token ':'"); } } // 爲下一個字段解析作準備 if (lexer.token() == JSONToken.COMMA) { continue; } if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); break; } if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) { throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token())); } } // 至此fastjson 解析就完成了 if (object == null) { if (fieldValues == null) { object = createInstance(parser, type); if (childContext == null) { childContext = parser.setContext(context, object, fieldName); } return (T) object; } String[] paramNames = beanInfo.creatorConstructorParameters; final Object[] params; if (paramNames != null) { params = new Object[paramNames.length]; for (int i = 0; i < paramNames.length; i++) { String paramName = paramNames[i]; Object param = fieldValues.remove(paramName); if (param == null) { Type fieldType = beanInfo.creatorConstructorParameterTypes[i]; FieldInfo fieldInfo = beanInfo.fields[i]; if (fieldType == byte.class) { param = (byte) 0; } else if (fieldType == short.class) { param = (short) 0; } else if (fieldType == int.class) { param = 0; } else if (fieldType == long.class) { param = 0L; } else if (fieldType == float.class) { param = 0F; } else if (fieldType == double.class) { param = 0D; } else if (fieldType == boolean.class) { param = Boolean.FALSE; } else if (fieldType == String.class && (fieldInfo.parserFeatures & Feature.InitStringFieldAsEmpty.mask) != 0) { param = ""; } } else { if (beanInfo.creatorConstructorParameterTypes != null && i < beanInfo.creatorConstructorParameterTypes.length) { Type paramType = beanInfo.creatorConstructorParameterTypes[i]; if (paramType instanceof Class) { Class paramClass = (Class) paramType; if (!paramClass.isInstance(param)) { if (param instanceof List) { List list = (List) param; if (list.size() == 1) { Object first = list.get(0); if (paramClass.isInstance(first)) { param = list.get(0); } } } } } } } params[i] = param; } } else { FieldInfo[] fieldInfoList = beanInfo.fields; int size = fieldInfoList.length; params = new Object[size]; for (int i = 0; i < size; ++i) { FieldInfo fieldInfo = fieldInfoList[i]; Object param = fieldValues.get(fieldInfo.name); if (param == null) { Type fieldType = fieldInfo.fieldType; if (fieldType == byte.class) { param = (byte) 0; } else if (fieldType == short.class) { param = (short) 0; } else if (fieldType == int.class) { param = 0; } else if (fieldType == long.class) { param = 0L; } else if (fieldType == float.class) { param = 0F; } else if (fieldType == double.class) { param = 0D; } else if (fieldType == boolean.class) { param = Boolean.FALSE; } else if (fieldType == String.class && (fieldInfo.parserFeatures & Feature.InitStringFieldAsEmpty.mask) != 0) { param = ""; } } params[i] = param; } } if (beanInfo.creatorConstructor != null) { boolean hasNull = false; if (beanInfo.kotlin) { for (int i = 0; i < params.length; i++) { if (params[i] == null && beanInfo.fields != null && i < beanInfo.fields.length) { FieldInfo fieldInfo = beanInfo.fields[i]; if (fieldInfo.fieldClass == String.class) { hasNull = true; } break; } } } try { if (hasNull && beanInfo.kotlinDefaultConstructor != null) { object = beanInfo.kotlinDefaultConstructor.newInstance(new Object[0]); for (int i = 0; i < params.length; i++) { final Object param = params[i]; if (param != null && beanInfo.fields != null && i < beanInfo.fields.length) { FieldInfo fieldInfo = beanInfo.fields[i]; fieldInfo.set(object, param); } } } else { object = beanInfo.creatorConstructor.newInstance(params); } } catch (Exception e) { throw new JSONException("create instance error, " + paramNames + ", " + beanInfo.creatorConstructor.toGenericString(), e); } if (paramNames != null) { for (Map.Entry<String, Object> entry : fieldValues.entrySet()) { FieldDeserializer fieldDeserializer = getFieldDeserializer(entry.getKey()); if (fieldDeserializer != null) { fieldDeserializer.setValue(object, entry.getValue()); } } } } else if (beanInfo.factoryMethod != null) { try { object = beanInfo.factoryMethod.invoke(null, params); } catch (Exception e) { throw new JSONException("create factory method error, " + beanInfo.factoryMethod.toString(), e); } } childContext.object = object; } // 還能夠再用 buildMethod 再修飾一翻, 若是有設置的話 Method buildMethod = beanInfo.buildMethod; if (buildMethod == null) { // 因建立時就是 T 類型,因此這裏直接強轉 return (T) object; } Object builtObj; try { builtObj = buildMethod.invoke(object); } catch (Exception e) { throw new JSONException("build object error", e); } return (T) builtObj; } finally { if (childContext != null) { childContext.object = object; } parser.setContext(context); } } // 解析字段值 public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType, Map<String, Object> fieldValues, int[] setFlags) { JSONLexer lexer = parser.lexer; // xxx final int disableFieldSmartMatchMask = Feature.DisableFieldSmartMatch.mask; FieldDeserializer fieldDeserializer; if (lexer.isEnabled(disableFieldSmartMatchMask) || (this.beanInfo.parserFeatures & disableFieldSmartMatchMask) != 0) { fieldDeserializer = getFieldDeserializer(key); } else { fieldDeserializer = smartMatch(key, setFlags); } final int mask = Feature.SupportNonPublicField.mask; if (fieldDeserializer == null && (lexer.isEnabled(mask) || (this.beanInfo.parserFeatures & mask) != 0)) { if (this.extraFieldDeserializers == null) { ConcurrentHashMap extraFieldDeserializers = new ConcurrentHashMap<String, Object>(1, 0.75f, 1); for (Class c = this.clazz; c != null && c != Object.class; c = c.getSuperclass()) { Field[] fields = c.getDeclaredFields(); for (Field field : fields) { String fieldName = field.getName(); if (this.getFieldDeserializer(fieldName) != null) { continue; } int fieldModifiers = field.getModifiers(); if ((fieldModifiers & Modifier.FINAL) != 0 || (fieldModifiers & Modifier.STATIC) != 0) { continue; } extraFieldDeserializers.put(fieldName, field); } } this.extraFieldDeserializers = extraFieldDeserializers; } Object deserOrField = extraFieldDeserializers.get(key); if (deserOrField != null) { if (deserOrField instanceof FieldDeserializer) { fieldDeserializer = ((FieldDeserializer) deserOrField); } else { Field field = (Field) deserOrField; field.setAccessible(true); FieldInfo fieldInfo = new FieldInfo(key, field.getDeclaringClass(), field.getType(), field.getGenericType(), field, 0, 0, 0); fieldDeserializer = new DefaultFieldDeserializer(parser.getConfig(), clazz, fieldInfo); extraFieldDeserializers.put(key, fieldDeserializer); } } } if (fieldDeserializer == null) { if (!lexer.isEnabled(Feature.IgnoreNotMatch)) { throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); } for (FieldDeserializer fieldDeser : this.sortedFieldDeserializers) { FieldInfo fieldInfo = fieldDeser.fieldInfo; if (fieldInfo.unwrapped // && fieldDeser instanceof DefaultFieldDeserializer) { if (fieldInfo.field != null) { DefaultFieldDeserializer defaultFieldDeserializer = (DefaultFieldDeserializer) fieldDeser; ObjectDeserializer fieldValueDeser = defaultFieldDeserializer.getFieldValueDeserilizer(parser.getConfig()); if (fieldValueDeser instanceof JavaBeanDeserializer) { JavaBeanDeserializer javaBeanFieldValueDeserializer = (JavaBeanDeserializer) fieldValueDeser; FieldDeserializer unwrappedFieldDeser = javaBeanFieldValueDeserializer.getFieldDeserializer(key); if (unwrappedFieldDeser != null) { Object fieldObject; try { fieldObject = fieldInfo.field.get(object); if (fieldObject == null) { fieldObject = ((JavaBeanDeserializer) fieldValueDeser).createInstance(parser, fieldInfo.fieldType); fieldDeser.setValue(object, fieldObject); } lexer.nextTokenWithColon(defaultFieldDeserializer.getFastMatchToken()); unwrappedFieldDeser.parseField(parser, fieldObject, objectType, fieldValues); return true; } catch (Exception e) { throw new JSONException("parse unwrapped field error.", e); } } } else if (fieldValueDeser instanceof MapDeserializer) { MapDeserializer javaBeanFieldValueDeserializer = (MapDeserializer) fieldValueDeser; Map fieldObject; try { fieldObject = (Map) fieldInfo.field.get(object); if (fieldObject == null) { fieldObject = javaBeanFieldValueDeserializer.createMap(fieldInfo.fieldType); fieldDeser.setValue(object, fieldObject); } lexer.nextTokenWithColon(); Object fieldValue = parser.parse(key); fieldObject.put(key, fieldValue); } catch (Exception e) { throw new JSONException("parse unwrapped field error.", e); } return true; } } else if (fieldInfo.method.getParameterTypes().length == 2) { lexer.nextTokenWithColon(); Object fieldValue = parser.parse(key); try { fieldInfo.method.invoke(object, key, fieldValue); } catch (Exception e) { throw new JSONException("parse unwrapped field error.", e); } return true; } } } parser.parseExtra(object, key); return false; } int fieldIndex = -1; for (int i = 0; i < sortedFieldDeserializers.length; ++i) { if (sortedFieldDeserializers[i] == fieldDeserializer) { fieldIndex = i; break; } } if (fieldIndex != -1 && setFlags != null && key.startsWith("_")) { if (isSetFlag(fieldIndex, setFlags)) { parser.parseExtra(object, key); return false; } } lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken()); // 調用 deserializer.parseField() fieldDeserializer.parseField(parser, object, objectType, fieldValues); return true; } // com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer @Override public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) { if (this.fieldValueDeserilizer == null) { getFieldValueDeserilizer(parser.getConfig()); } ObjectDeserializer fieldValueDeserilizer = this.fieldValueDeserilizer; Type fieldType = fieldInfo.fieldType; if (objectType instanceof ParameterizedType) { ParseContext objContext = parser.getContext(); if (objContext != null) { objContext.type = objectType; } if (fieldType != objectType) { fieldType = FieldInfo.getFieldType(this.clazz, objectType, fieldType); fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType); } } // ContextObjectDeserializer Object value; if (fieldValueDeserilizer instanceof JavaBeanDeserializer && fieldInfo.parserFeatures != 0) { JavaBeanDeserializer javaBeanDeser = (JavaBeanDeserializer) fieldValueDeserilizer; value = javaBeanDeser.deserialze(parser, fieldType, fieldInfo.name, fieldInfo.parserFeatures); } else { if (this.fieldInfo.format != null && fieldValueDeserilizer instanceof ContextObjectDeserializer) { value = ((ContextObjectDeserializer) fieldValueDeserilizer) // .deserialze(parser, fieldType, fieldInfo.name, fieldInfo.format, fieldInfo.parserFeatures); } else { value = fieldValueDeserilizer.deserialze(parser, fieldType, fieldInfo.name); } } if (value instanceof byte[] && ("gzip".equals(fieldInfo.format) || "gzip,base64".equals(fieldInfo.format))) { byte[] bytes = (byte[]) value; GZIPInputStream gzipIn = null; try { gzipIn = new GZIPInputStream(new ByteArrayInputStream(bytes)); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); for (;;) { byte[] buf = new byte[1024]; int len = gzipIn.read(buf); if (len == -1) { break; } if (len > 0) { byteOut.write(buf, 0, len); } } value = byteOut.toByteArray(); } catch (IOException ex) { throw new JSONException("unzip bytes error.", ex); } } if (parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) { ResolveTask task = parser.getLastResolveTask(); task.fieldDeserializer = this; task.ownerContext = parser.getContext(); parser.setResolveStatus(DefaultJSONParser.NONE); } else { if (object == null) { fieldValues.put(fieldInfo.name, value); } else { // 將解析出的字段值放入原對象中, 即 ResponseEntity // 此處的字段信息已已知,因此只須要將對象傳入便可, fieldInfo.method setValue(object, value); } } } // com.alibaba.fastjson.parser.deserializer.MapDeserializer @SuppressWarnings("unchecked") public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { if (type == JSONObject.class && parser.getFieldTypeResolver() == null) { return (T) parser.parseObject(); } final JSONLexer lexer = parser.lexer; if (lexer.token() == JSONToken.NULL) { lexer.nextToken(JSONToken.COMMA); return null; } // 建立空map Map<Object, Object> map = createMap(type); ParseContext context = parser.getContext(); try { parser.setContext(context, map, fieldName); return (T) deserialze(parser, type, fieldName, map); } finally { parser.setContext(context); } } @SuppressWarnings({ "unchecked", "rawtypes" }) public Map<Object, Object> createMap(Type type) { if (type == Properties.class) { return new Properties(); } if (type == Hashtable.class) { return new Hashtable(); } if (type == IdentityHashMap.class) { return new IdentityHashMap(); } if (type == SortedMap.class || type == TreeMap.class) { return new TreeMap(); } if (type == ConcurrentMap.class || type == ConcurrentHashMap.class) { return new ConcurrentHashMap(); } if (type == Map.class || type == HashMap.class) { return new HashMap(); } if (type == LinkedHashMap.class) { return new LinkedHashMap(); } if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; Type rawType = parameterizedType.getRawType(); if (EnumMap.class.equals(rawType)) { Type[] actualArgs = parameterizedType.getActualTypeArguments(); return new EnumMap((Class) actualArgs[0]); } // 通用map再遞歸建立, 其實就是建立一個 HashMap return createMap(rawType); } Class<?> clazz = (Class<?>) type; if (clazz.isInterface()) { throw new JSONException("unsupport type " + type); } try { return (Map<Object, Object>) clazz.newInstance(); } catch (Exception e) { throw new JSONException("unsupport type " + type, e); } } // 最後,來看 map 是如何解析的吧:分兩步, 1. key 的解析; 2. value 的解析 @SuppressWarnings({ "rawtypes", "unchecked" }) protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, Map map) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; // key 的類型取第一個 type Type keyType = parameterizedType.getActualTypeArguments()[0]; Type valueType = null; if(map.getClass().getName().equals("org.springframework.util.LinkedMultiValueMap")){ valueType = List.class; }else{ // value 的類型取第二個 type valueType = parameterizedType.getActualTypeArguments()[1]; } // 到此,整個 泛型的推導就完成了,後面就是對值的解析了 if (String.class == keyType) { return parseMap(parser, (Map<String, Object>) map, valueType, fieldName); } else { return parseMap(parser, map, keyType, valueType, fieldName); } } else { return parser.parseObject(map, fieldName); } } @SuppressWarnings("rawtypes") public static Map parseMap(DefaultJSONParser parser, Map<String, Object> map, Type valueType, Object fieldName) { JSONLexer lexer = parser.lexer; int token = lexer.token(); if (token != JSONToken.LBRACE) { String msg = "syntax error, expect {, actual " + lexer.tokenName(); if (fieldName instanceof String) { msg += ", fieldName "; msg += fieldName; } msg += ", "; msg += lexer.info(); if (token != JSONToken.LITERAL_STRING) { JSONArray array = new JSONArray(); parser.parseArray(array, fieldName); if (array.size() == 1) { Object first = array.get(0); if (first instanceof JSONObject) { return (JSONObject) first; } } } throw new JSONException(msg); } ParseContext context = parser.getContext(); try { for (int i = 0;;++i) { lexer.skipWhitespace(); char ch = lexer.getCurrent(); if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { while (ch == ',') { lexer.next(); lexer.skipWhitespace(); ch = lexer.getCurrent(); } } String key; if (ch == '"') { // 按 '"' 進行分隔,得出第一個 key, 即 orderId key = lexer.scanSymbol(parser.getSymbolTable(), '"'); lexer.skipWhitespace(); ch = lexer.getCurrent(); if (ch != ':') { throw new JSONException("expect ':' at " + lexer.pos()); } } else if (ch == '}') { lexer.next(); lexer.resetStringPosition(); lexer.nextToken(JSONToken.COMMA); return map; } else if (ch == '\'') { if (!lexer.isEnabled(Feature.AllowSingleQuotes)) { throw new JSONException("syntax error"); } key = lexer.scanSymbol(parser.getSymbolTable(), '\''); lexer.skipWhitespace(); ch = lexer.getCurrent(); if (ch != ':') { throw new JSONException("expect ':' at " + lexer.pos()); } } else { if (!lexer.isEnabled(Feature.AllowUnQuotedFieldNames)) { throw new JSONException("syntax error"); } key = lexer.scanSymbolUnQuoted(parser.getSymbolTable()); lexer.skipWhitespace(); ch = lexer.getCurrent(); if (ch != ':') { throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch); } } // key 解析完成後,解析下一個 lexer.next(); lexer.skipWhitespace(); ch = lexer.getCurrent(); // 重置解析開始 lexer.resetStringPosition(); if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) { String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"'); final ParserConfig config = parser.getConfig(); Class<?> clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); if (Map.class.isAssignableFrom(clazz) ) { lexer.nextToken(JSONToken.COMMA); if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); return map; } continue; } ObjectDeserializer deserializer = config.getDeserializer(clazz); lexer.nextToken(JSONToken.COMMA); parser.setResolveStatus(DefaultJSONParser.TypeNameRedirect); if (context != null && !(fieldName instanceof Integer)) { parser.popContext(); } return (Map) deserializer.deserialze(parser, clazz, fieldName); } Object value; lexer.nextToken(); if (i != 0) { parser.setContext(context); } if (lexer.token() == JSONToken.NULL) { value = null; lexer.nextToken(); } else { value = parser.parseObject(valueType, key); } // 是否須要 ResolveFieldDeserializer 處理一遍 map.put(key, value); parser.checkMapResolve(map, key); parser.setContext(context, value, key); parser.setContext(context); final int tok = lexer.token(); if (tok == JSONToken.EOF || tok == JSONToken.RBRACKET) { return map; } if (tok == JSONToken.RBRACE) { // 解析完成 lexer.nextToken(); return map; } } } finally { parser.setContext(context); } } // com.alibaba.fastjson.parser.JSONLexerBase public final String scanSymbol(final SymbolTable symbolTable, final char quote) { int hash = 0; np = bp; sp = 0; boolean hasSpecial = false; char chLocal; for (;;) { chLocal = next(); // 遇到下一個分符則中止, 轉義符除外 if (chLocal == quote) { break; } if (chLocal == EOI) { throw new JSONException("unclosed.str"); } // 遇到轉義符時,會向後推動一位斷定 if (chLocal == '\\') { if (!hasSpecial) { hasSpecial = true; if (sp >= sbuf.length) { int newCapcity = sbuf.length * 2; if (sp > newCapcity) { newCapcity = sp; } char[] newsbuf = new char[newCapcity]; System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); sbuf = newsbuf; } // text.getChars(np + 1, np + 1 + sp, sbuf, 0); // System.arraycopy(this.buf, np + 1, sbuf, 0, sp); arrayCopy(np + 1, sbuf, 0, sp); } chLocal = next(); switch (chLocal) { case '0': hash = 31 * hash + (int) chLocal; putChar('\0'); break; case '1': hash = 31 * hash + (int) chLocal; putChar('\1'); break; case '2': hash = 31 * hash + (int) chLocal; putChar('\2'); break; case '3': hash = 31 * hash + (int) chLocal; putChar('\3'); break; case '4': hash = 31 * hash + (int) chLocal; putChar('\4'); break; case '5': hash = 31 * hash + (int) chLocal; putChar('\5'); break; case '6': hash = 31 * hash + (int) chLocal; putChar('\6'); break; case '7': hash = 31 * hash + (int) chLocal; putChar('\7'); break; case 'b': // 8 hash = 31 * hash + (int) '\b'; putChar('\b'); break; case 't': // 9 hash = 31 * hash + (int) '\t'; putChar('\t'); break; case 'n': // 10 hash = 31 * hash + (int) '\n'; putChar('\n'); break; case 'v': // 11 hash = 31 * hash + (int) '\u000B'; putChar('\u000B'); break; case 'f': // 12 case 'F': hash = 31 * hash + (int) '\f'; putChar('\f'); break; case 'r': // 13 hash = 31 * hash + (int) '\r'; putChar('\r'); break; case '"': // 34 hash = 31 * hash + (int) '"'; putChar('"'); break; case '\'': // 39 hash = 31 * hash + (int) '\''; putChar('\''); break; case '/': // 47 hash = 31 * hash + (int) '/'; putChar('/'); break; case '\\': // 92 hash = 31 * hash + (int) '\\'; putChar('\\'); break; // 16進制數據 case 'x': char x1 = ch = next(); char x2 = ch = next(); int x_val = digits[x1] * 16 + digits[x2]; char x_char = (char) x_val; hash = 31 * hash + (int) x_char; putChar(x_char); break; // unicode 編碼 case 'u': char c1 = chLocal = next(); char c2 = chLocal = next(); char c3 = chLocal = next(); char c4 = chLocal = next(); int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16); hash = 31 * hash + val; putChar((char) val); break; default: this.ch = chLocal; throw new JSONException("unclosed.str.lit"); } continue; } hash = 31 * hash + chLocal; if (!hasSpecial) { sp++; continue; } if (sp == sbuf.length) { putChar(chLocal); } else { sbuf[sp++] = chLocal; } } token = LITERAL_STRING; String value; if (!hasSpecial) { // return this.text.substring(np + 1, np + 1 + sp).intern(); int offset; if (np == -1) { offset = 0; } else { // 向後推動計算位 offset = np + 1; } // 取出相應value value = addSymbol(offset, sp, hash, symbolTable); } else { value = symbolTable.addSymbol(sbuf, 0, sp, hash); } // 解析下一個作準備, ':' 分隔符跳過 sp = 0; this.next(); return value; } public final String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable) { return symbolTable.addSymbol(text, offset, len, hash); } // com.alibaba.fastjson.parser.SymbolTable public String addSymbol(String buffer, int offset, int len, int hash) { return addSymbol(buffer, offset, len, hash, false); } public String addSymbol(String buffer, int offset, int len, int hash, boolean replace) { // 根據 hash 定位value, final int bucket = hash & indexMask; String symbol = symbols[bucket]; if (symbol != null) { if (hash == symbol.hashCode() // && len == symbol.length() // && buffer.startsWith(symbol, offset)) { return symbol; } String str = subString(buffer, offset, len); if (replace) { symbols[bucket] = str; } return str; } symbol = len == buffer.length() // ? buffer // : subString(buffer, offset, len); symbol = symbol.intern(); // 沒有解析出則如今存入 symbols symbols[bucket] = symbol; return symbol; }
總結: 泛型推斷其實很簡單: 1. 普通泛型會被jdk封裝爲 TypeVariableImpl, 而複合泛型則會被封裝爲 ParameterizedTypeImpl; 2. 經過 Class.getGenericSuperclass(), 能夠獲取完整泛型信息類; 3. 經過 (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0] 能夠獲取完整泛型; 4. 經過 ParameterizedType.getRawType() 獲取運行時的類信息; 5. 經過 ParameterizedType.getActualTypeArguments() 獲取泛型的內部信息; 6. 對於多泛型傳遞致使的類型丟失,在 TypeReference 構造函數傳入原始信息,進行對應還原便可; 7. 固然本文說了不少其餘廢話;(json的解析過程)