给你一组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 的变化,可以使用泛型去适应变化;
其次,data下的数据是 key -> object 的结构,如果直接object表示的话,又不友好了。如果不以object表示,针对不同的object又如何是好?答案是,再抽象一层泛型出来就行了;
最终的数据结构就是这样: ResponseEntity<T> ---> ResponseEntity<Map<String, T>> , 具体bean就不用写了吧!
其实做这一步的解析,还是容易的。不过,具体怎么做,就不一定了。
另一个问题,解析这些数据结构,我需要再封装得简单点,因为底层的数据访问步骤都是一样的,我不想重复造轮子!比如,我只需要在最上层转入想要转化的数据结构类型,就可以得到不一样的数据对象!
这个当然很简单,只需要使用泛型方法就行了。简单示例如下:
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,这其实不重要。
重要的是,你认为,如上代码能成功达到要求吗???
不管怎么样,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 View Code
很神奇,泛型居然还在!!! 其实这只在字节码保留的 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); } View Code
序列化构造器详情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. } View Code
解析
// 获取到 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. 当然本文说了很多其他废话;