从fastjson多层泛型嵌套解析,看jdk泛型推断
给你一组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 --; size bytes
MD5 checksum e8b36dfda241162b15ada875df4345e0
Compiled from "CapitalUtilsTest"
public class com.test.CapitalUtilsTest
minor version:
major version:
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
# = Methodref #.# // java.lang.Object."<init>":()V
# = Methodref #.# // com.test.CapitalUtilsTest.parseMoreGenericParams:()Lcom.test.ResponseEntity;
# = Fieldref #.# // java.lang.System.out:Ljava.io.PrintStream;
# = Class # // java.lang.StringBuilder
# = Methodref #.# // java.lang.StringBuilder."<init>":()V
# = String # // result:
# = Methodref #.# // java.lang.StringBuilder.append:(Ljava.lang.String;)Ljava.lang.StringBuilder;
# = Methodref #.# // java.lang.StringBuilder.append:(Ljava.lang.Object;)Ljava.lang.StringBuilder;
# = Methodref #.# // java.lang.StringBuilder.toString:()Ljava.lang.String;
# = Methodref #.# // java.io.PrintStream.println:(Ljava.lang.String;)V
# = String # // {\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}
# = Class # // com.test.CapitalUtilsTest$1
# = Methodref #.# // com.test.CapitalUtilsTest$1."<init>":(Lcom.test.CapitalUtilsTest;)V
# = Class # // com.alibaba.fastjson.parser.Feature
# = Methodref #.# // com.alibaba.fastjson.JSONObject.parseObject:(Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object;
# = Class # // com.test.ResponseEntity
# = Class # // com.test.CapitalUtilsTest
# = Class # // java.lang.Object
# = Utf8 InnerClasses
# = Utf8 <init>
# = Utf8 ()V
# = Utf8 Code
# = Utf8 LineNumberTable
# = Utf8 LocalVariableTable
# = Utf8 this
# = Utf8 Lcom.test.CapitalUtilsTest;
# = Utf8 testInnerGenericAnalyze
# = Utf8 result
# = Utf8 Lcom.test.ResponseEntity;
# = Utf8 LocalVariableTypeTable
# = Utf8 Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;Lcom.test.OrderDetail;>;>;
# = Utf8 RuntimeVisibleAnnotations
# = Utf8 Lorg.junit.Test;
# = Utf8 parseMoreGenericParams
# = Utf8 ()Lcom.test.ResponseEntity;
# = Utf8 json
# = Utf8 Ljava.lang.String;
# = Utf8 Signature
# = Utf8 <T:Ljava.lang.Object;>()Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;TT;>;>;
# = Utf8 SourceFile
# = Utf8 CapitalUtilsTest
# = NameAndType #:# // "<init>":()V
# = NameAndType #:# // parseMoreGenericParams:()Lcom.test.ResponseEntity;
# = Class # // java.lang.System
# = NameAndType #:# // out:Ljava.io.PrintStream;
# = Utf8 java.lang.StringBuilder
# = Utf8 result:
# = NameAndType #:# // append:(Ljava.lang.String;)Ljava.lang.StringBuilder;
# = NameAndType #:# // append:(Ljava.lang.Object;)Ljava.lang.StringBuilder;
# = NameAndType #:# // toString:()Ljava.lang.String;
# = Class # // java.io.PrintStream
# = NameAndType #:# // println:(Ljava.lang.String;)V
# = Utf8 {\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}
# = Utf8 com.test.CapitalUtilsTest$
# = NameAndType #:# // "<init>":(Lcom.test.CapitalUtilsTest;)V
# = Utf8 com.alibaba.fastjson.parser.Feature
# = Class # // com.alibaba.fastjson.JSONObject
# = NameAndType #:# // parseObject:(Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object;
# = Utf8 com.test.ResponseEntity
# = Utf8 com.test.CapitalUtilsTest
# = Utf8 java.lang.Object
# = Utf8 java.lang.System
# = Utf8 out
# = Utf8 Ljava.io.PrintStream;
# = Utf8 append
# = Utf8 (Ljava.lang.String;)Ljava.lang.StringBuilder;
# = Utf8 (Ljava.lang.Object;)Ljava.lang.StringBuilder;
# = Utf8 toString
# = Utf8 ()Ljava.lang.String;
# = Utf8 java.io.PrintStream
# = Utf8 println
# = Utf8 (Ljava.lang.String;)V
# = Utf8 (Lcom.test.CapitalUtilsTest;)V
# = Utf8 com.alibaba.fastjson.JSONObject
# = Utf8 parseObject
# = 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=, locals=, args_size=
: aload_0
: invokespecial # // Method java.lang.Object."<init>":()V
: return
LineNumberTable:
line :
LocalVariableTable:
Start Length Slot Name Signature
this Lcom.test.CapitalUtilsTest; public void testInnerGenericAnalyze();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=, locals=, args_size=
: aload_0
: invokespecial # // Method parseMoreGenericParams:()Lcom.test.ResponseEntity;
: astore_1
: getstatic # // Field java.lang.System.out:Ljava.io.PrintStream;
: new # // class java.lang.StringBuilder
: dup
: invokespecial # // Method java.lang.StringBuilder."<init>":()V
: ldc # // String result:
: invokevirtual # // Method java.lang.StringBuilder.append:(Ljava.lang.String;)Ljava.lang.StringBuilder;
: aload_1
: invokevirtual # // Method java.lang.StringBuilder.append:(Ljava.lang.Object;)Ljava.lang.StringBuilder;
: invokevirtual # // Method java.lang.StringBuilder.toString:()Ljava.lang.String;
: invokevirtual # // Method java.io.PrintStream.println:(Ljava.lang.String;)V
: return
LineNumberTable:
line :
line :
line :
LocalVariableTable:
Start Length Slot Name Signature
this Lcom.test.CapitalUtilsTest;
result Lcom.test.ResponseEntity;
LocalVariableTypeTable:
Start Length Slot Name Signature
result Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;Lcom.test.OrderDetail;>;>;
RuntimeVisibleAnnotations:
: #() 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=, locals=, args_size=
: ldc # // String {\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}
: astore_1
: aload_1
: new # // class com.test.CapitalUtilsTest$1
: dup
: aload_0
: invokespecial # // Method com.test.CapitalUtilsTest$1."<init>":(Lcom.test.CapitalUtilsTest;)V
: iconst_0
: anewarray # // class com.alibaba.fastjson.parser.Feature
: invokestatic # // Method com.alibaba.fastjson.JSONObject.parseObject:(Ljava.lang.String;Lcom.alibaba.fastjson.TypeReference;[Lcom.alibaba.fastjson.parser.Feature;)Ljava.lang.Object;
: checkcast # // class com.test.ResponseEntity
: areturn
LineNumberTable:
line :
line :
LocalVariableTable:
Start Length Slot Name Signature
this Lcom.test.CapitalUtilsTest;
json Ljava.lang.String;
Signature: # // <T:Ljava.lang.Object;>()Lcom.test.ResponseEntity<Ljava.util.Map<Ljava.lang.String;TT;>;>;
}
SourceFile: "CapitalUtilsTest"
InnerClasses:
#; //class com.test.CapitalUtilsTest$1
很神奇,泛型居然还在!!! 其实这只在字节码保留的 signature, 实际在运行时已经不在了!
所以,第二次封装后,只剩下了object了,所以,最终解析出来的 map 的 value 会变成 jsonobject 就不足为奇了。
这看起来很完美,好像这条路走不通了。那么,我想转换出内部具体类型怎么办?
我们知道,fastjson 中想要解析泛型,就是通过 new TypeReference<>(){} 来实现的,那为什么它能实现,而我们却不能实现呢?我们先看下 TypeReference 的泛型推断原理吧!
package com.alibaba.fastjson; import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import com.alibaba.fastjson.util.ParameterizedTypeImpl;
import com.alibaba.fastjson.util.TypeUtils; /**
* Represents a generic type {@code T}. Java doesn't yet provide a way to
* represent generic types, so this class does. Forces clients to create a
* subclass of this class which enables retrieval the type information even at
* runtime.
*
* <p>For example, to create a type literal for {@code List<String>}, you can
* create an empty anonymous inner class:
*
* <pre>
* TypeReference<List<String>> list = new TypeReference<List<String>>() {};
* </pre>
* This syntax cannot be used to create type literals that have wildcard
* parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}.
*/
public class TypeReference<T> {
static ConcurrentMap<Type, Type> classTypeCache
= new ConcurrentHashMap<Type, Type>(16, 0.75f, 1); protected final Type type; // 一般情况下,我们使用此默认构造器就足够了
/**
* Constructs a new type literal. Derives represented class from type
* parameter.
*
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
* parameter in the anonymous class's type hierarchy so we can reconstitute it
* at runtime despite erasure.
*/
protected TypeReference(){
// 先获取完整的泛型类,从这里可以看出,jdk的泛型虽然是擦除式的,但仍然是有迹可寻的
// TypeReference<List<String>>
Type superClass = getClass().getGenericSuperclass(); // 接着,从完整的类型定义中,取出真正的泛型类型,比如 java.util.List<String>
Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
} this.type = cachedType;
} /**
* @since 1.2.9
* @param actualTypeArguments
*/
protected TypeReference(Type... actualTypeArguments){
Class<?> thisClass = this.getClass();
Type superClass = thisClass.getGenericSuperclass(); // 先直接获取传入 TypeReference 的泛型信息 ResponseEntity<Map<String, T>>
ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0];
// 获取无泛型类 ResponseEntity
Type rawType = argType.getRawType();
// 再获取第一层泛型信息, Map<String, T>
Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0;
for (int i = 0; i < argTypes.length; ++i) {
// ParameterizedTypeImpl
if (argTypes[i] instanceof TypeVariable &&
actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
}
// fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = TypeUtils.checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
} // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
// 复杂类型都会被解析为 ParameterizedType 类型
// 而类似于 T 这种泛型,则会被解析为 TypeVariableImpl
if(argTypes[i] instanceof ParameterizedType) {
argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
}
} // ParameterizedTypeImpl 的 hashCode() 是采用 ownerType + rawType + actualTypeArguments 进行判定的,所以 cache 会有用
Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
Type cachedType = classTypeCache.get(key);
if (cachedType == null) {
classTypeCache.putIfAbsent(key, key);
cachedType = classTypeCache.get(key);
} // 放入缓存后返回
type = cachedType; }
// ParameterizedTypeImpl.equals()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; ParameterizedTypeImpl that = (ParameterizedTypeImpl) o; // Probably incorrect - comparing Object[] arrays with Arrays.equals
if (!Arrays.equals(actualTypeArguments, that.actualTypeArguments)) return false;
if (ownerType != null ? !ownerType.equals(that.ownerType) : that.ownerType != null) return false;
return rawType != null ? rawType.equals(that.rawType) : that.rawType == null; }
// ParameterizedTypeImpl.hashCode()
@Override
public int hashCode() {
int result = actualTypeArguments != null ? Arrays.hashCode(actualTypeArguments) : 0;
result = 31 * result + (ownerType != null ? ownerType.hashCode() : 0);
result = 31 * result + (rawType != null ? rawType.hashCode() : 0);
return result;
} // 相当于递归解析
private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) {
Class<?> thisClass = this.getClass();
Type rawType = type.getRawType();
Type[] argTypes = type.getActualTypeArguments(); for(int i = 0; i < argTypes.length; ++i) {
if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) {
// 通过位置一一对应。 1. 是 TypeVariable 即是 T 这样的泛型, 如 <T1, T2, T3>, 则传入的构造参数也应该是 (T1, T2, T3), 否则将对应错误
argTypes[i] = actualTypeArguments[actualIndex++];
} // fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = TypeUtils.checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
} // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
// 多层则递归
if(argTypes[i] instanceof ParameterizedType) {
return handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
}
} // 重新 new 一个 ParameterizedTypeImpl 出来返回
Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
return key;
} /**
* Gets underlying {@code Type} instance.
*/
public Type getType() {
return type;
} // 最开始就会初始化一个 LIST_STRING 的类型备用
public final static Type LIST_STRING = new TypeReference<List<String>>() {}.getType();
}
我们很容易想到的,就是在外部结果中,进行循环后,进行类型转换,然后再插入到原始key中。这看起来其实也不坏,但是,你这样反复循环操作,是不是有点耗性能了;另外,我还得写很多重复的代码啊。
所以,我们还得更优雅的方法吗?当然你可以不用转,直接取jsonobject对象的值也是可以的;
所以,更优雅的实现应该是从本质上解决问题。但是,从jdk的编译原理上,它是做不到泛型传递了。那怎么办?既然jdk会进行类型擦除,我们进行一次类型还原,是不是就能解决了?是的,思路如此。
具体实现,则是将具体的泛型类,以class方式传入方法中,然后在方法进行类型还原即可!
具体我们来看下fastjson的实现:
1. fastjson是如何解析普通泛型的?
2. fastjson是如何解析多层嵌套泛型的?
3. fastjson是如何还原泛型传递的?
我们一个个来源码:JsonObject.parseObject(); 首先对于无泛型对象,直接给出原始类就可以了。
// com.alibaba.fastjson.JSON, 添加 DEFAULT_PARSER_FEATURE=989
/**
* <pre>
* String jsonStr = "[{\"id\":1001,\"name\":\"Jobs\"}]";
* List<Model> models = JSON.parseObject(jsonStr, new TypeReference<List<Model>>() {});
* </pre>
* @param text json string
* @param type type refernce
* @param features
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T parseObject(String text, TypeReference<T> type, Feature... features) {
return (T) parseObject(text, type.type, ParserConfig.global, DEFAULT_PARSER_FEATURE, features);
} public static <T> T parseObject(String input, Type clazz, ParserConfig config, int featureValues,
Feature... features) {
return parseObject(input, clazz, config, null, featureValues, features);
} @SuppressWarnings("unchecked")
public static <T> T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor,
int featureValues, Feature... features) {
// null 直接返回 null
if (input == null) {
return null;
} // feature 默认为空
if (features != null) {
for (Feature feature : features) {
featureValues |= feature.mask;
}
} // 使用 DefaultJSONParser 解析, 将配置参数传入
DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues); // processor 不为空,则添加处理逻辑
if (processor != null) {
if (processor instanceof ExtraTypeProvider) {
parser.getExtraTypeProviders().add((ExtraTypeProvider) processor);
} if (processor instanceof ExtraProcessor) {
parser.getExtraProcessors().add((ExtraProcessor) processor);
} if (processor instanceof FieldTypeResolver) {
parser.setFieldTypeResolver((FieldTypeResolver) processor);
}
} // 直接调用 DefaultJSONParser.parseObject()
T value = (T) parser.parseObject(clazz, null); // 处理 value resolveTask(),
parser.handleResovleTask(value); // 关闭输出流
parser.close(); return (T) value;
}
如上,就是json的的主流程,其实关键就在于 DefaultJSONParser 。如上操作就分几步:
1. 分析 feature, 设置好, 关键是之前new 的 TypeReference 作为类信息传入配置;
2. 将配置项全部载入 DefaultJSONParser 中, 以备后续使用;
3. processor 配置添加;
4. 调用 DefaultJSONParser.parseObject(), 做真正的解析动作;
5. 异步 task 处理;
6. 关闭输出流,并返回值;
所以,我们主要来看 DefaultJSONParser 的处理逻辑;
// com.alibaba.fastjson.parser.DefaultJSONParser
public DefaultJSONParser(final String input, final ParserConfig config, int features){
// 初始化 JSONScanner -> JSONLexerBase, JSONScanner 将作为一个解析管道,顺序解析结果
// 而 input 则作为一个原始值存在
this(input, new JSONScanner(input, features), config);
} public DefaultJSONParser(final Object input, final JSONLexer lexer, final ParserConfig config){
this.lexer = lexer;
this.input = input;
this.config = config;
this.symbolTable = config.symbolTable; int ch = lexer.getCurrent();
// 根据第一个字符来判定要解析的类型, 以 "{" 开始的是json对象, "[" 开头的是 json 数组, 其他的直接取下一个字符串
if (ch == '{') {
lexer.next();
((JSONLexerBase) lexer).token = JSONToken.LBRACE;
} else if (ch == '[') {
lexer.next();
((JSONLexerBase) lexer).token = JSONToken.LBRACKET;
} else {
lexer.nextToken(); // prime the pump
}
} // 初始化好之后,进行关键的解析动作 parseObject()
@SuppressWarnings("unchecked")
public <T> T parseObject(Type type, Object fieldName) {
// 把在构造函数中判断出的 token 类型, 取出判定
int token = lexer.token();
if (token == JSONToken.NULL) {
lexer.nextToken();
return null;
} if (token == JSONToken.LITERAL_STRING) {
if (type == byte[].class) {
byte[] bytes = lexer.bytesValue();
lexer.nextToken();
return (T) bytes;
} if (type == char[].class) {
String strVal = lexer.stringVal();
lexer.nextToken();
return (T) strVal.toCharArray();
}
} // 关键: 获取反序列化器, 此处的type就是 TypeReference 推断出的 type
// 实际类型为: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
// 我们稍后看一下是如何获取反序列化器的
ObjectDeserializer derializer = config.getDeserializer(type); try {
if (derializer.getClass() == JavaBeanDeserializer.class) {
// 对于复杂类型的解析, 单独转换后调入, feature 为 0
return (T) ((JavaBeanDeserializer) derializer).deserialze(this, type, fieldName, 0);
} else {
return (T) derializer.deserialze(this, type, fieldName);
}
} catch (JSONException e) {
throw e;
} catch (Throwable e) {
throw new JSONException(e.getMessage(), e);
}
} // com.alibaba.fastjson.parser.ParserConfig , 获取反序列化器
public ObjectDeserializer getDeserializer(Type type) {
ObjectDeserializer derializer = this.deserializers.get(type);
if (derializer != null) {
return derializer;
} if (type instanceof Class<?>) {
return getDeserializer((Class<?>) type, type);
} // 通过 TypeReference 指定类型的type 为 ParameterizedTypeImpl, 所以会走此分支
if (type instanceof ParameterizedType) {
// 会取出最外层的 泛型 class, 以决定使用哪种 derializer
Type rawType = ((ParameterizedType) type).getRawType();
if (rawType instanceof Class<?>) {
// 如果外层泛型为 class, 则进行实际泛型解析,否则递归操作先
return getDeserializer((Class<?>) rawType, type);
} else {
return getDeserializer(rawType);
}
} if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
Type[] upperBounds = wildcardType.getUpperBounds();
if (upperBounds.length == 1) {
Type upperBoundType = upperBounds[0];
return getDeserializer(upperBoundType);
}
} return JavaObjectDeserializer.instance;
}
// 多重缓存并查
public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
ObjectDeserializer derializer = deserializers.get(type);
if (derializer != null) {
return derializer;
} if (type == null) {
type = clazz;
} // 排除 type 为空的情况,再次查询 derializers 缓存
derializer = deserializers.get(type);
if (derializer != null) {
return derializer;
} {
// 使用 JSONType 注释的类处理
JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
if (annotation != null) {
Class<?> mappingTo = annotation.mappingTo();
if (mappingTo != Void.class) {
return getDeserializer(mappingTo, mappingTo);
}
}
} // 直接通过主类 clazz 获取反序列化器
if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
derializer = deserializers.get(clazz);
} if (derializer != null) {
return derializer;
} // 经过上面的筛选,仍然没有值,只能新计算了
String className = clazz.getName();
className = className.replace('$', '.'); // awt 类库特殊处理
if (className.startsWith("java.awt.") //
&& AwtCodec.support(clazz)) {
if (!awtError) {
String[] names = new String[] {
"java.awt.Point",
"java.awt.Font",
"java.awt.Rectangle",
"java.awt.Color"
}; try {
for (String name : names) {
if (name.equals(className)) {
deserializers.put(Class.forName(name), derializer = AwtCodec.instance);
return derializer;
}
}
} catch (Throwable e) {
// skip
awtError = true;
} derializer = AwtCodec.instance;
}
} // jdk8 的特殊类的解析
if (!jdk8Error) {
try {
if (className.startsWith("java.time.")) {
String[] names = new String[] {
"java.time.LocalDateTime",
"java.time.LocalDate",
"java.time.LocalTime",
"java.time.ZonedDateTime",
"java.time.OffsetDateTime",
"java.time.OffsetTime",
"java.time.ZoneOffset",
"java.time.ZoneRegion",
"java.time.ZoneId",
"java.time.Period",
"java.time.Duration",
"java.time.Instant"
}; for (String name : names) {
if (name.equals(className)) {
deserializers.put(Class.forName(name), derializer = Jdk8DateCodec.instance);
return derializer;
}
}
} else if (className.startsWith("java.util.Optional")) {
String[] names = new String[] {
"java.util.Optional",
"java.util.OptionalDouble",
"java.util.OptionalInt",
"java.util.OptionalLong"
};
for (String name : names) {
if (name.equals(className)) {
deserializers.put(Class.forName(name), derializer = OptionalCodec.instance);
return derializer;
}
}
}
} catch (Throwable e) {
// skip
jdk8Error = true;
}
} if (className.equals("java.nio.file.Path")) {
deserializers.put(clazz, derializer = MiscCodec.instance);
} if (clazz == Map.Entry.class) {
deserializers.put(clazz, derializer = MiscCodec.instance);
} final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
// 是否指定自定义的反序列化器?
for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class,
classLoader)) {
for (Type forType : autowired.getAutowiredFor()) {
deserializers.put(forType, autowired);
}
}
} catch (Exception ex) {
// skip
} if (derializer == null) {
derializer = deserializers.get(type);
} if (derializer != null) {
return derializer;
} // 各种类型依次判定
if (clazz.isEnum()) {
Class<?> deserClass = null;
JSONType jsonType = clazz.getAnnotation(JSONType.class);
if (jsonType != null) {
deserClass = jsonType.deserializer();
try {
derializer = (ObjectDeserializer) deserClass.newInstance();
deserializers.put(clazz, derializer);
return derializer;
} catch (Throwable error) {
// skip
}
} derializer = new EnumDeserializer(clazz);
} else if (clazz.isArray()) {
derializer = ObjectArrayCodec.instance;
} else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class
|| clazz == ArrayList.class) {
derializer = CollectionCodec.instance;
} else if (Collection.class.isAssignableFrom(clazz)) {
derializer = CollectionCodec.instance;
} else if (Map.class.isAssignableFrom(clazz)) {
derializer = MapDeserializer.instance;
} else if (Throwable.class.isAssignableFrom(clazz)) {
derializer = new ThrowableDeserializer(this, clazz);
} else if (PropertyProcessable.class.isAssignableFrom(clazz)) {
derializer = new PropertyProcessableDeserializer((Class<PropertyProcessable>) clazz);
} else if (clazz == InetAddress.class) {
derializer = MiscCodec.instance;
} else {
// 最后,其实会落到通用的 javaBeanDesializer 上, 这个创建可不简单,我们稍后看一下
derializer = createJavaBeanDeserializer(clazz, type);
} // 最后,将结果存入缓存,以便下一次查找
putDeserializer(type, derializer); return derializer;
}
// 创建一个普通 javaBeanDesializer, type 中保存有所有的原始泛型类型,泛型的推断主要在这里看到
public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
boolean asmEnable = this.asmEnable & !this.fieldBased;
if (asmEnable) {
JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class); if (jsonType != null) {
Class<?> deserializerClass = jsonType.deserializer();
if (deserializerClass != Void.class) {
try {
Object deseralizer = deserializerClass.newInstance();
if (deseralizer instanceof ObjectDeserializer) {
return (ObjectDeserializer) deseralizer;
}
} catch (Throwable e) {
// skip
}
} asmEnable = jsonType.asm();
} if (asmEnable) {
// 优先查看 注解上的定义
Class<?> superClass = JavaBeanInfo.getBuilderClass(clazz, jsonType);
if (superClass == null) {
superClass = clazz;
} for (;;) {
if (!Modifier.isPublic(superClass.getModifiers())) {
asmEnable = false;
break;
} superClass = superClass.getSuperclass();
if (superClass == Object.class || superClass == null) {
break;
}
}
}
} // 此处会取 T 的类型
if (clazz.getTypeParameters().length != 0) {
asmEnable = false;
} if (asmEnable && asmFactory != null && asmFactory.classLoader.isExternalClass(clazz)) {
asmEnable = false;
} if (asmEnable) {
asmEnable = ASMUtils.checkName(clazz.getSimpleName());
} if (asmEnable) {
if (clazz.isInterface()) {
asmEnable = false;
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy); if (asmEnable && beanInfo.fields.length > 200) {
asmEnable = false;
} Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
if (asmEnable && defaultConstructor == null && !clazz.isInterface()) {
asmEnable = false;
} for (FieldInfo fieldInfo : beanInfo.fields) {
if (fieldInfo.getOnly) {
asmEnable = false;
break;
} Class<?> fieldClass = fieldInfo.fieldClass;
if (!Modifier.isPublic(fieldClass.getModifiers())) {
asmEnable = false;
break;
} if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) {
asmEnable = false;
break;
} if (fieldInfo.getMember() != null //
&& !ASMUtils.checkName(fieldInfo.getMember().getName())) {
asmEnable = false;
break;
} JSONField annotation = fieldInfo.getAnnotation();
if (annotation != null //
&& ((!ASMUtils.checkName(annotation.name())) //
|| annotation.format().length() != 0 //
|| annotation.deserializeUsing() != Void.class //
|| annotation.unwrapped())
|| (fieldInfo.method != null && fieldInfo.method.getParameterTypes().length > 1)) {
asmEnable = false;
break;
} if (fieldClass.isEnum()) { // EnumDeserializer
ObjectDeserializer fieldDeser = this.getDeserializer(fieldClass);
if (!(fieldDeser instanceof EnumDeserializer)) {
asmEnable = false;
break;
}
}
}
} if (asmEnable) {
if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
asmEnable = false;
}
} // 总之,前面的判断都只是为了检查是否可以使用 asm 进行反序列化
if (!asmEnable) {
// 不能则返回 JavaBeanDeserializer
return new JavaBeanDeserializer(this, clazz, type);
} JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, type, propertyNamingStrategy);
try {
return asmFactory.createJavaBeanDeserializer(this, beanInfo);
// } catch (VerifyError e) {
// e.printStackTrace();
// return new JavaBeanDeserializer(this, clazz, type);
} catch (NoSuchMethodException ex) {
return new JavaBeanDeserializer(this, clazz, type);
} catch (JSONException asmError) {
return new JavaBeanDeserializer(this, beanInfo);
} catch (Exception e) {
throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
}
}
序列化器构造详情
// com.alibaba.fastjson.parser.deserializerBeanDeserializer
public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){
// 此处 JavaBeanInfo 的创建也是大工程啊,
this(config //
, JavaBeanInfo.build(clazz, type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean)
);
} public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){
this.clazz = beanInfo.clazz;
this.beanInfo = beanInfo; Map<String, FieldDeserializer> alterNameFieldDeserializers = null;
sortedFieldDeserializers = new FieldDeserializer[beanInfo.sortedFields.length];
for (int i = 0, size = beanInfo.sortedFields.length; i < size; ++i) {
FieldInfo fieldInfo = beanInfo.sortedFields[i];
FieldDeserializer fieldDeserializer = config.createFieldDeserializer(config, beanInfo, fieldInfo); sortedFieldDeserializers[i] = fieldDeserializer; for (String name : fieldInfo.alternateNames) {
if (alterNameFieldDeserializers == null) {
alterNameFieldDeserializers = new HashMap<String, FieldDeserializer>();
}
alterNameFieldDeserializers.put(name, fieldDeserializer);
}
}
this.alterNameFieldDeserializers = alterNameFieldDeserializers; fieldDeserializers = new FieldDeserializer[beanInfo.fields.length];
for (int i = 0, size = beanInfo.fields.length; i < size; ++i) {
FieldInfo fieldInfo = beanInfo.fields[i];
// 此处会使用已排好序的 sortedFieldDeserializers 进行查找
FieldDeserializer fieldDeserializer = getFieldDeserializer(fieldInfo.name);
fieldDeserializers[i] = fieldDeserializer;
}
} // com.alibaba.fastjson.utilBeanInfo, 几百行的 JavaBeanInfo 的创建过程
public static JavaBeanInfo build(Class<?> clazz //
, Type type //
, PropertyNamingStrategy propertyNamingStrategy //
, boolean fieldBased //
, boolean compatibleWithJavaBean
) {
JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
if (jsonType != null) {
PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
if (jsonTypeNaming != null && jsonTypeNaming != PropertyNamingStrategy.CamelCase) {
propertyNamingStrategy = jsonTypeNaming;
}
} Class<?> builderClass = getBuilderClass(clazz, jsonType); // 取出字段和方法
Field[] declaredFields = clazz.getDeclaredFields();
Method[] methods = clazz.getMethods(); boolean kotlin = TypeUtils.isKotlin(clazz);
Constructor[] constructors = clazz.getDeclaredConstructors(); Constructor<?> defaultConstructor = null;
if ((!kotlin) || constructors.length == 1) {
if (builderClass == null) {
// 默认无参构造器
defaultConstructor = getDefaultConstructor(clazz, constructors);
} else {
defaultConstructor = getDefaultConstructor(builderClass, builderClass.getDeclaredConstructors());
}
} Constructor<?> creatorConstructor = null;
Method buildMethod = null;
Method factoryMethod = null; List<FieldInfo> fieldList = new ArrayList<FieldInfo>(); if (fieldBased) {
for (Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) {
Field[] fields = currentClass.getDeclaredFields(); computeFields(clazz, type, propertyNamingStrategy, fieldList, fields);
}
return new JavaBeanInfo(clazz, builderClass, defaultConstructor, null, factoryMethod, buildMethod, jsonType, fieldList);
} boolean isInterfaceOrAbstract = clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers());
if ((defaultConstructor == null && builderClass == null) || isInterfaceOrAbstract) {
creatorConstructor = getCreatorConstructor(constructors); if (creatorConstructor != null && !isInterfaceOrAbstract) { // 基于标记 JSONCreator 注解的构造方法
TypeUtils.setAccessible(creatorConstructor); Class<?>[] types = creatorConstructor.getParameterTypes(); String[] lookupParameterNames = null;
if (types.length > 0) {
Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
for (int i = 0; i < types.length; ++i) {
Annotation[] paramAnnotations = paramAnnotationArrays[i];
JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
fieldAnnotation = (JSONField) paramAnnotation;
break;
}
} Class<?> fieldClass = types[i];
Type fieldType = creatorConstructor.getGenericParameterTypes()[i]; String fieldName = null;
Field field = null;
int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
if (fieldAnnotation != null) {
field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields);
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
fieldName = fieldAnnotation.name();
} if (fieldName == null || fieldName.length() == 0) {
if (lookupParameterNames == null) {
lookupParameterNames = ASMUtils.lookupParameterNames(creatorConstructor);
}
fieldName = lookupParameterNames[i];
} FieldInfo fieldInfo = new FieldInfo(fieldName, clazz, fieldClass, fieldType, field,
ordinal, serialzeFeatures, parserFeatures);
add(fieldList, fieldInfo);
}
} //return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList);
} else if ((factoryMethod = getFactoryMethod(clazz, methods)) != null) {
TypeUtils.setAccessible(factoryMethod); Class<?>[] types = factoryMethod.getParameterTypes();
if (types.length > 0) {
Annotation[][] paramAnnotationArrays = factoryMethod.getParameterAnnotations();
for (int i = 0; i < types.length; ++i) {
Annotation[] paramAnnotations = paramAnnotationArrays[i];
JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
fieldAnnotation = (JSONField) paramAnnotation;
break;
}
}
if (fieldAnnotation == null) {
throw new JSONException("illegal json creator");
} Class<?> fieldClass = types[i];
Type fieldType = factoryMethod.getGenericParameterTypes()[i];
Field field = TypeUtils.getField(clazz, fieldAnnotation.name(), declaredFields);
final int ordinal = fieldAnnotation.ordinal();
final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
final int parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field,
ordinal, serialzeFeatures, parserFeatures);
add(fieldList, fieldInfo);
} return new JavaBeanInfo(clazz, builderClass, null, null, factoryMethod, null, jsonType, fieldList);
}
} else if (!isInterfaceOrAbstract) {
String className = clazz.getName(); String[] paramNames = null;
if (kotlin && constructors.length > 0) {
paramNames = TypeUtils.getKoltinConstructorParameters(clazz);
creatorConstructor = TypeUtils.getKoltinConstructor(constructors, paramNames);
TypeUtils.setAccessible(creatorConstructor);
} else { for (Constructor constructor : constructors) {
Class<?>[] parameterTypes = constructor.getParameterTypes(); if (className.equals("org.springframework.security.web.authentication.WebAuthenticationDetails")) {
if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) {
creatorConstructor = constructor;
creatorConstructor.setAccessible(true);
paramNames = ASMUtils.lookupParameterNames(constructor);
break;
}
} if (className.equals("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken")) {
if (parameterTypes.length == 3
&& parameterTypes[0] == Object.class
&& parameterTypes[1] == Object.class
&& parameterTypes[2] == Collection.class) {
creatorConstructor = constructor;
creatorConstructor.setAccessible(true);
paramNames = new String[] {"principal", "credentials", "authorities"};
break;
}
} if (className.equals("org.springframework.security.core.authority.SimpleGrantedAuthority")) {
if (parameterTypes.length == 1
&& parameterTypes[0] == String.class) {
creatorConstructor = constructor;
paramNames = new String[] {"authority"};
break;
}
} // boolean is_public = (constructor.getModifiers() & Modifier.PUBLIC) != 0;
if (!is_public) {
continue;
}
String[] lookupParameterNames = ASMUtils.lookupParameterNames(constructor);
if (lookupParameterNames == null || lookupParameterNames.length == 0) {
continue;
} if (creatorConstructor != null
&& paramNames != null && lookupParameterNames.length <= paramNames.length) {
continue;
} paramNames = lookupParameterNames;
creatorConstructor = constructor;
}
} Class<?>[] types = null;
if (paramNames != null) {
types = creatorConstructor.getParameterTypes();
} if (paramNames != null
&& types.length == paramNames.length) {
Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
for (int i = 0; i < types.length; ++i) {
Annotation[] paramAnnotations = paramAnnotationArrays[i];
String paramName = paramNames[i]; JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
fieldAnnotation = (JSONField) paramAnnotation;
break;
}
} Class<?> fieldClass = types[i];
Type fieldType = creatorConstructor.getGenericParameterTypes()[i];
Field field = TypeUtils.getField(clazz, paramName, declaredFields);
if (field != null) {
if (fieldAnnotation == null) {
fieldAnnotation = field.getAnnotation(JSONField.class);
}
}
final int ordinal, serialzeFeatures, parserFeatures;
if (fieldAnnotation == null) {
ordinal = 0;
serialzeFeatures = 0; if ("org.springframework.security.core.userdetails.User".equals(className)
&& "password".equals(paramName)) {
parserFeatures = Feature.InitStringFieldAsEmpty.mask;
} else {
parserFeatures = 0;
}
} else {
String nameAnnotated = fieldAnnotation.name();
if (nameAnnotated.length() != 0) {
paramName = nameAnnotated;
}
ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
}
FieldInfo fieldInfo = new FieldInfo(paramName, clazz, fieldClass, fieldType, field,
ordinal, serialzeFeatures, parserFeatures);
add(fieldList, fieldInfo);
} if ((!kotlin)
&& !clazz.getName().equals("javax.servlet.http.Cookie")) {
return new JavaBeanInfo(clazz, builderClass, null, creatorConstructor, null, null, jsonType, fieldList);
}
} else {
throw new JSONException("default constructor not found. " + clazz);
}
}
} if (defaultConstructor != null) {
TypeUtils.setAccessible(defaultConstructor);
} if (builderClass != null) {
String withPrefix = null; JSONPOJOBuilder builderAnno = builderClass.getAnnotation(JSONPOJOBuilder.class);
if (builderAnno != null) {
withPrefix = builderAnno.withPrefix();
} if (withPrefix == null || withPrefix.length() == 0) {
withPrefix = "with";
} for (Method method : builderClass.getMethods()) {
if (Modifier.isStatic(method.getModifiers())) {
continue;
} if (!(method.getReturnType().equals(builderClass))) {
continue;
} int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0; JSONField annotation = method.getAnnotation(JSONField.class); if (annotation == null) {
annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);
} if (annotation != null) {
if (!annotation.deserialize()) {
continue;
} ordinal = annotation.ordinal();
serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
parserFeatures = Feature.of(annotation.parseFeatures()); if (annotation.name().length() != 0) {
String propertyName = annotation.name();
add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures,
annotation, null, null));
continue;
}
} String methodName = method.getName();
StringBuilder properNameBuilder;
if (methodName.startsWith("set") && methodName.length() > 3) {
properNameBuilder = new StringBuilder(methodName.substring(3));
} else {
if (!methodName.startsWith(withPrefix)) {
continue;
} if (methodName.length() <= withPrefix.length()) {
continue;
} properNameBuilder = new StringBuilder(methodName.substring(withPrefix.length()));
} char c0 = properNameBuilder.charAt(0);
if (!Character.isUpperCase(c0)) {
continue;
} properNameBuilder.setCharAt(0, Character.toLowerCase(c0)); String propertyName = properNameBuilder.toString(); add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures,
annotation, null, null));
} if (builderClass != null) {
JSONPOJOBuilder builderAnnotation = builderClass.getAnnotation(JSONPOJOBuilder.class); String buildMethodName = null;
if (builderAnnotation != null) {
buildMethodName = builderAnnotation.buildMethod();
} if (buildMethodName == null || buildMethodName.length() == 0) {
buildMethodName = "build";
} try {
buildMethod = builderClass.getMethod(buildMethodName);
} catch (NoSuchMethodException e) {
// skip
} catch (SecurityException e) {
// skip
} if (buildMethod == null) {
try {
buildMethod = builderClass.getMethod("create");
} catch (NoSuchMethodException e) {
// skip
} catch (SecurityException e) {
// skip
}
} if (buildMethod == null) {
throw new JSONException("buildMethod not found.");
} TypeUtils.setAccessible(buildMethod);
}
} for (Method method : methods) { //
int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
String methodName = method.getName(); if (Modifier.isStatic(method.getModifiers())) {
continue;
} // support builder set
Class<?> returnType = method.getReturnType();
if (!(returnType.equals(Void.TYPE) || returnType.equals(method.getDeclaringClass()))) {
continue;
} if (method.getDeclaringClass() == Object.class) {
continue;
} Class<?>[] types = method.getParameterTypes(); if (types.length == 0 || types.length > 2) {
continue;
} JSONField annotation = method.getAnnotation(JSONField.class);
if (annotation != null
&& types.length == 2
&& types[0] == String.class
&& types[1] == Object.class) {
add(fieldList, new FieldInfo("", method, null, clazz, type, ordinal,
serialzeFeatures, parserFeatures, annotation, null, null));
continue;
} if (types.length != 1) {
continue;
} if (annotation == null) {
annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);
} if (annotation == null && methodName.length() < 4) {
continue;
} if (annotation != null) {
if (!annotation.deserialize()) {
continue;
} ordinal = annotation.ordinal();
serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
parserFeatures = Feature.of(annotation.parseFeatures()); if (annotation.name().length() != 0) {
String propertyName = annotation.name();
add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures, parserFeatures,
annotation, null, null));
continue;
}
} if (annotation == null && !methodName.startsWith("set")) { // TODO "set"的判断放在 JSONField 注解后面,意思是允许非 setter 方法标记 JSONField 注解?
continue;
} char c3 = methodName.charAt(3); String propertyName;
if (Character.isUpperCase(c3) //
|| c3 > 512 // for unicode method name
) {
if (TypeUtils.compatibleWithJavaBean) {
propertyName = TypeUtils.decapitalize(methodName.substring(3));
} else {
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
}
} else if (c3 == '_') {
propertyName = methodName.substring(4);
} else if (c3 == 'f') {
propertyName = methodName.substring(3);
} else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) {
propertyName = TypeUtils.decapitalize(methodName.substring(3));
} else {
continue;
} Field field = TypeUtils.getField(clazz, propertyName, declaredFields);
if (field == null && types[0] == boolean.class) {
String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
field = TypeUtils.getField(clazz, isFieldName, declaredFields);
} JSONField fieldAnnotation = null;
if (field != null) {
fieldAnnotation = field.getAnnotation(JSONField.class); if (fieldAnnotation != null) {
if (!fieldAnnotation.deserialize()) {
continue;
} ordinal = fieldAnnotation.ordinal();
serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
parserFeatures = Feature.of(fieldAnnotation.parseFeatures()); if (fieldAnnotation.name().length() != 0) {
propertyName = fieldAnnotation.name();
add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal,
serialzeFeatures, parserFeatures, annotation, fieldAnnotation, null));
continue;
}
} } if (propertyNamingStrategy != null) {
propertyName = propertyNamingStrategy.translate(propertyName);
}
// 添加解析出的字段到 fieldList 中
add(fieldList, new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures,
annotation, fieldAnnotation, null));
} // 因为在上面加入了一些字段,所以现在重新取字段
Field[] fields = clazz.getFields();
computeFields(clazz, type, propertyNamingStrategy, fieldList, fields); for (Method method : clazz.getMethods()) { // getter methods
String methodName = method.getName();
if (methodName.length() < 4) {
continue;
} if (Modifier.isStatic(method.getModifiers())) {
continue;
} if (builderClass == null && methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3))) {
if (method.getParameterTypes().length != 0) {
continue;
} if (Collection.class.isAssignableFrom(method.getReturnType()) //
|| Map.class.isAssignableFrom(method.getReturnType()) //
|| AtomicBoolean.class == method.getReturnType() //
|| AtomicInteger.class == method.getReturnType() //
|| AtomicLong.class == method.getReturnType() //
) {
String propertyName; JSONField annotation = method.getAnnotation(JSONField.class);
if (annotation != null && annotation.deserialize()) {
continue;
} if (annotation != null && annotation.name().length() > 0) {
propertyName = annotation.name();
} else {
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); Field field = TypeUtils.getField(clazz, propertyName, declaredFields);
if (field != null) {
JSONField fieldAnnotation = field.getAnnotation(JSONField.class);
if (fieldAnnotation != null && !fieldAnnotation.deserialize()) {
continue;
}
}
} if (propertyNamingStrategy != null) {
propertyName = propertyNamingStrategy.translate(propertyName);
} FieldInfo fieldInfo = getField(fieldList, propertyName);
if (fieldInfo != null) {
continue;
} add(fieldList, new FieldInfo(propertyName, method, null, clazz, type, 0, 0, 0, annotation, null, null));
}
}
}
// 最后返回 JavaBeanInfo
return new JavaBeanInfo(clazz, builderClass, defaultConstructor, creatorConstructor, factoryMethod, buildMethod, jsonType, fieldList);
}
序列化构造器详情2:
// com.alibaba.fastjson.util.FieldInfo , 构建字段信息
public FieldInfo(String name, //
Method method, //
Field field, //
Class<?> clazz, //
Type type, //
int ordinal, //
int serialzeFeatures, //
int parserFeatures, //
JSONField fieldAnnotation, //
JSONField methodAnnotation, //
String label){
if (field != null) {
String fieldName = field.getName();
if (fieldName.equals(name)) {
name = fieldName;
}
} if (ordinal < 0) {
ordinal = 0;
} this.name = name;
this.method = method;
this.field = field;
this.ordinal = ordinal;
this.serialzeFeatures = serialzeFeatures;
this.parserFeatures = parserFeatures;
this.fieldAnnotation = fieldAnnotation;
this.methodAnnotation = methodAnnotation; if (field != null) {
int modifiers = field.getModifiers();
fieldAccess = ((modifiers & Modifier.PUBLIC) != 0 || method == null);
fieldTransient = Modifier.isTransient(modifiers)
|| TypeUtils.isTransient(method);
} else {
fieldAccess = false;
fieldTransient = false;
} if (label != null && label.length() > 0) {
this.label = label;
} else {
this.label = "";
} String format = null;
JSONField annotation = getAnnotation(); boolean jsonDirect = false;
if (annotation != null) {
format = annotation.format(); if (format.trim().length() == 0) {
format = null;
}
jsonDirect = annotation.jsonDirect();
unwrapped = annotation.unwrapped();
alternateNames = annotation.alternateNames();
} else {
jsonDirect = false;
unwrapped = false;
alternateNames = new String[0];
}
this.format = format; name_chars = genFieldNameChars(); if (method != null) {
TypeUtils.setAccessible(method);
} if (field != null) {
TypeUtils.setAccessible(field);
} boolean getOnly = false;
Type fieldType;
Class<?> fieldClass;
if (method != null) {
Class<?>[] types;
if ((types = method.getParameterTypes()).length == 1) {
// 泛型在此变为 java.lang.Object
// 所以,泛型的推断关键,就交给了 type 字段的设值了
fieldClass = types[0];
// 泛型可推断出值, 如题中 Map<String, T>, 此处将得出 T 的 TypeVariableImpl , 但是 fieldClass = java.lang.Object
fieldType = method.getGenericParameterTypes()[0];
} else if (types.length == 2 && types[0] == String.class && types[1] == Object.class) {
fieldType = fieldClass = types[0];
} else {
fieldClass = method.getReturnType();
fieldType = method.getGenericReturnType();
getOnly = true;
}
this.declaringClass = method.getDeclaringClass();
} else {
fieldClass = field.getType();
fieldType = field.getGenericType();
this.declaringClass = field.getDeclaringClass();
getOnly = Modifier.isFinal(field.getModifiers());
}
this.getOnly = getOnly;
this.jsonDirect = jsonDirect && fieldClass == String.class; if (clazz != null && fieldClass == Object.class && fieldType instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) fieldType;
// 再次通过原始指定的泛型进行一次推断,得到泛型的真正类,从而达到还原泛型的目的
// 泛型的继承关系推断
Type genericFieldType = getInheritGenericType(clazz, type, tv);
if (genericFieldType != null) {
this.fieldClass = TypeUtils.getClass(genericFieldType);
this.fieldType = genericFieldType; isEnum = fieldClass.isEnum();
return;
}
} Type genericFieldType = fieldType; if (!(fieldType instanceof Class)) {
genericFieldType = getFieldType(clazz, type != null ? type : clazz, fieldType); if (genericFieldType != fieldType) {
if (genericFieldType instanceof ParameterizedType) {
fieldClass = TypeUtils.getClass(genericFieldType);
} else if (genericFieldType instanceof Class) {
fieldClass = TypeUtils.getClass(genericFieldType);
}
}
} this.fieldType = genericFieldType;
this.fieldClass = fieldClass; isEnum = fieldClass.isEnum();
} private static Type getInheritGenericType(Class<?> clazz, Type type, TypeVariable<?> tv) {
GenericDeclaration gd = tv.getGenericDeclaration(); Class<?> class_gd = null;
if (gd instanceof Class) {
class_gd = (Class<?>) tv.getGenericDeclaration();
} Type[] arguments = null;
if (class_gd == clazz) {
// 泛型的还原都是通过 ParameterizedType 来实现的
// 此处会一层层还原,如题的操作第一层还原将得到 java.util.Map<String, T>
// 所以,泛型的推断关键,就交给了 type 字段的设值了
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
// 设置的泛型会在此处进行体现
arguments = ptype.getActualTypeArguments();
}
} else {
for (Class<?> c = clazz; c != null && c != Object.class && c != class_gd; c = c.getSuperclass()) {
Type superType = c.getGenericSuperclass(); if (superType instanceof ParameterizedType) {
ParameterizedType p_superType = (ParameterizedType) superType;
Type[] p_superType_args = p_superType.getActualTypeArguments();
getArgument(p_superType_args, c.getTypeParameters(), arguments);
arguments = p_superType_args;
}
}
} if (arguments == null || class_gd == null) {
return null;
} Type actualType = null;
// 此处将会获取到泛型 T, 与 将 tv 与 typeVariables 进行比较,如果找到设置值则,得出泛型的原型,以待后用
TypeVariable<?>[] typeVariables = class_gd.getTypeParameters();
for (int j = 0; j < typeVariables.length; ++j) {
// 最终的泛型结果,在查找中得到
if (tv.equals(typeVariables[j])) {
actualType = arguments[j];
break;
}
}
// Map<String, T>
return actualType;
} private static Type getInheritGenericType(Class<?> clazz, Type type, TypeVariable<?> tv) {
GenericDeclaration gd = tv.getGenericDeclaration(); Class<?> class_gd = null;
if (gd instanceof Class) {
class_gd = (Class<?>) tv.getGenericDeclaration();
} Type[] arguments = null;
if (class_gd == clazz) {
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
arguments = ptype.getActualTypeArguments();
}
} else {
for (Class<?> c = clazz; c != null && c != Object.class && c != class_gd; c = c.getSuperclass()) {
Type superType = c.getGenericSuperclass(); if (superType instanceof ParameterizedType) {
ParameterizedType p_superType = (ParameterizedType) superType;
Type[] p_superType_args = p_superType.getActualTypeArguments();
getArgument(p_superType_args, c.getTypeParameters(), arguments);
arguments = p_superType_args;
}
}
} if (arguments == null || class_gd == null) {
return null;
} Type actualType = null;
TypeVariable<?>[] typeVariables = class_gd.getTypeParameters();
for (int j = 0; j < typeVariables.length; ++j) {
if (tv.equals(typeVariables[j])) {
actualType = arguments[j];
break;
}
} return actualType;
} // 参数配置好后,new JavaBeanInfo()
public JavaBeanInfo(Class<?> clazz, //
Class<?> builderClass, //
Constructor<?> defaultConstructor, //
Constructor<?> creatorConstructor, //
Method factoryMethod, //
Method buildMethod, //
JSONType jsonType, //
List<FieldInfo> fieldList) {
this.clazz = clazz;
this.builderClass = builderClass;
this.defaultConstructor = defaultConstructor;
this.creatorConstructor = creatorConstructor;
this.factoryMethod = factoryMethod;
this.parserFeatures = TypeUtils.getParserFeatures(clazz);
this.buildMethod = buildMethod; this.jsonType = jsonType;
if (jsonType != null) {
String typeName = jsonType.typeName();
String typeKey = jsonType.typeKey();
this.typeKey = typeKey.length() > 0 ? typeKey : null; if (typeName.length() != 0) {
this.typeName = typeName;
} else {
this.typeName = clazz.getName();
}
String[] orders = jsonType.orders();
this.orders = orders.length == 0 ? null : orders;
} else {
this.typeName = clazz.getName();
this.typeKey = null;
this.orders = null;
} // 字段信息
fields = new FieldInfo[fieldList.size()];
fieldList.toArray(fields); FieldInfo[] sortedFields = new FieldInfo[fields.length];
if (orders != null) {
LinkedHashMap<String, FieldInfo> map = new LinkedHashMap<String, FieldInfo>(fieldList.size());
for (FieldInfo field : fields) {
map.put(field.name, field);
}
int i = 0;
for (String item : orders) {
FieldInfo field = map.get(item);
if (field != null) {
sortedFields[i++] = field;
map.remove(item);
}
}
for (FieldInfo field : map.values()) {
sortedFields[i++] = field;
}
} else {
System.arraycopy(fields, 0, sortedFields, 0, fields.length);
Arrays.sort(sortedFields);
} if (Arrays.equals(fields, sortedFields)) {
sortedFields = fields;
}
this.sortedFields = sortedFields; if (defaultConstructor != null) {
defaultConstructorParameterSize = defaultConstructor.getParameterTypes().length;
} else if (factoryMethod != null) {
defaultConstructorParameterSize = factoryMethod.getParameterTypes().length;
} else {
defaultConstructorParameterSize = 0;
} if (creatorConstructor != null) {
this.creatorConstructorParameterTypes = creatorConstructor.getParameterTypes(); kotlin = TypeUtils.isKotlin(clazz);
if (kotlin) {
this.creatorConstructorParameters = TypeUtils.getKoltinConstructorParameters(clazz);
try {
this.kotlinDefaultConstructor = clazz.getConstructor();
} catch (Throwable ex) {
// skip
} Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
for (int i = 0; i < creatorConstructorParameters.length && i < paramAnnotationArrays.length; ++i) {
Annotation[] paramAnnotations = paramAnnotationArrays[i];
JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
fieldAnnotation = (JSONField) paramAnnotation;
break;
}
}
if (fieldAnnotation != null) {
String fieldAnnotationName = fieldAnnotation.name();
if (fieldAnnotationName.length() > 0) {
creatorConstructorParameters[i] = fieldAnnotationName;
}
}
}
} else {
boolean match;
if (creatorConstructorParameterTypes.length != fields.length) {
match = false;
} else {
match = true;
for (int i = 0; i < creatorConstructorParameterTypes.length; i++) {
if (creatorConstructorParameterTypes[i] != fields[i].fieldClass) {
match = false;
break;
}
}
} if (!match) {
this.creatorConstructorParameters = ASMUtils.lookupParameterNames(creatorConstructor);
}
}
}
} // com.alibaba.fastjson.parser.deserializerBeanDeserializer
public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){
this(config //
, JavaBeanInfo.build(clazz, type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean)
);
} public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){
this.clazz = beanInfo.clazz;
this.beanInfo = beanInfo; Map<String, FieldDeserializer> alterNameFieldDeserializers = null;
sortedFieldDeserializers = new FieldDeserializer[beanInfo.sortedFields.length];
for (int i = 0, size = beanInfo.sortedFields.length; i < size; ++i) {
// 将前端解析出的字段配置取出, 为每个字段创建一个解析器
FieldInfo fieldInfo = beanInfo.sortedFields[i];
FieldDeserializer fieldDeserializer = config.createFieldDeserializer(config, beanInfo, fieldInfo);
// 将对应的反序列化器放入到对应的位置
sortedFieldDeserializers[i] = fieldDeserializer; for (String name : fieldInfo.alternateNames) {
if (alterNameFieldDeserializers == null) {
alterNameFieldDeserializers = new HashMap<String, FieldDeserializer>();
}
alterNameFieldDeserializers.put(name, fieldDeserializer);
}
}
this.alterNameFieldDeserializers = alterNameFieldDeserializers; fieldDeserializers = new FieldDeserializer[beanInfo.fields.length];
for (int i = 0, size = beanInfo.fields.length; i < size; ++i) {
FieldInfo fieldInfo = beanInfo.fields[i];
// 根据 key 查找序列化器, 使用二分查找法
FieldDeserializer fieldDeserializer = getFieldDeserializer(fieldInfo.name);
fieldDeserializers[i] = fieldDeserializer;
}
} // com.alibaba.fastjson.parser.ParserConfig
public FieldDeserializer createFieldDeserializer(ParserConfig mapping, //
JavaBeanInfo beanInfo, //
FieldInfo fieldInfo) {
Class<?> clazz = beanInfo.clazz;
Class<?> fieldClass = fieldInfo.fieldClass; Class<?> deserializeUsing = null;
JSONField annotation = fieldInfo.getAnnotation();
if (annotation != null) {
deserializeUsing = annotation.deserializeUsing();
if (deserializeUsing == Void.class) {
deserializeUsing = null;
}
} if (deserializeUsing == null && (fieldClass == List.class || fieldClass == ArrayList.class)) {
return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
} return new DefaultFieldDeserializer(mapping, clazz, fieldInfo);
} public FieldDeserializer getFieldDeserializer(String key) {
return getFieldDeserializer(key, null);
} public FieldDeserializer getFieldDeserializer(String key, int[] setFlags) {
if (key == null) {
return null;
} int low = 0;
int high = sortedFieldDeserializers.length - 1; while (low <= high) {
int mid = (low + high) >>> 1; String fieldName = sortedFieldDeserializers[mid].fieldInfo.name; int cmp = fieldName.compareTo(key); if (cmp < 0) {
low = mid + 1;
} else if (cmp > 0) {
high = mid - 1;
} else {
if (isSetFlag(mid, setFlags)) {
return null;
} return sortedFieldDeserializers[mid]; // key found
}
} if(this.alterNameFieldDeserializers != null){
return this.alterNameFieldDeserializers.get(key);
} return null; // key not found.
}
解析
// 获取到 Serializer 后,就进行 derialize() 处理了!
// 流程如下
// com.alibaba.fastjson.parser.deserializerBeanDeserializer
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName, int features) {
return deserialze(parser, type, fieldName, null, features, null);
}
// 一长串的解析动作
@SuppressWarnings({ "unchecked", "rawtypes" })
protected <T> T deserialze(DefaultJSONParser parser, //
Type type, //
Object fieldName, //
Object object, //
int features, //
int[] setFlags) {
if (type == JSON.class || type == JSONObject.class) {
return (T) parser.parse();
}
// 获取配置, parser 为 DefaultJSONParser
final JSONLexerBase lexer = (JSONLexerBase) parser.lexer; // xxx
final ParserConfig config = parser.getConfig(); int token = lexer.token();
if (token == JSONToken.NULL) {
lexer.nextToken(JSONToken.COMMA);
return null;
} ParseContext context = parser.getContext();
if (object != null && context != null) {
context = context.parent;
}
ParseContext childContext = null; try {
Map<String, Object> fieldValues = null; if (token == JSONToken.RBRACE) {
lexer.nextToken(JSONToken.COMMA);
if (object == null) {
object = createInstance(parser, type);
}
return (T) object;
} if (token == JSONToken.LBRACKET) {
final int mask = Feature.SupportArrayToBean.mask;
boolean isSupportArrayToBean = (beanInfo.parserFeatures & mask) != 0 //
|| lexer.isEnabled(Feature.SupportArrayToBean) //
|| (features & mask) != 0
;
if (isSupportArrayToBean) {
return deserialzeArrayMapping(parser, type, fieldName, object);
}
} if (token != JSONToken.LBRACE && token != JSONToken.COMMA) {
if (lexer.isBlankInput()) {
return null;
} if (token == JSONToken.LITERAL_STRING) {
String strVal = lexer.stringVal();
if (strVal.length() == 0) {
lexer.nextToken();
return null;
} if (beanInfo.jsonType != null) {
for (Class<?> seeAlsoClass : beanInfo.jsonType.seeAlso()) {
if (Enum.class.isAssignableFrom(seeAlsoClass)) {
try {
Enum<?> e = Enum.valueOf((Class<Enum>) seeAlsoClass, strVal);
return (T) e;
} catch (IllegalArgumentException e) {
// skip
}
}
}
}
} else if (token == JSONToken.LITERAL_ISO8601_DATE) {
Calendar calendar = lexer.getCalendar();
} if (token == JSONToken.LBRACKET && lexer.getCurrent() == ']') {
lexer.next();
lexer.nextToken();
return null;
} StringBuilder buf = (new StringBuilder()) //
.append("syntax error, expect {, actual ") //
.append(lexer.tokenName()) //
.append(", pos ") //
.append(lexer.pos()); if (fieldName instanceof String) {
buf //
.append(", fieldName ") //
.append(fieldName);
} buf.append(", fastjson-version ").append(JSON.VERSION); throw new JSONException(buf.toString());
} if (parser.resolveStatus == DefaultJSONParser.TypeNameRedirect) {
parser.resolveStatus = DefaultJSONParser.NONE;
} // 解析单个 field
String typeKey = beanInfo.typeKey;
for (int fieldIndex = 0;; fieldIndex++) {
String key = null;
FieldDeserializer fieldDeser = null;
FieldInfo fieldInfo = null;
Class<?> fieldClass = null;
JSONField feildAnnotation = null;
boolean customDeserilizer = false;
if (fieldIndex < sortedFieldDeserializers.length) {
fieldDeser = sortedFieldDeserializers[fieldIndex];
fieldInfo = fieldDeser.fieldInfo;
fieldClass = fieldInfo.fieldClass;
feildAnnotation = fieldInfo.getAnnotation();
if (feildAnnotation != null && fieldDeser instanceof DefaultFieldDeserializer) {
customDeserilizer = ((DefaultFieldDeserializer) fieldDeser).customDeserilizer;
}
} boolean matchField = false;
boolean valueParsed = false;
// 先根据类型,解析出各字段的字段名
Object fieldValue = null;
if (fieldDeser != null) {
char[] name_chars = fieldInfo.name_chars;
if (customDeserilizer && lexer.matchField(name_chars)) {
matchField = true;
} else if (fieldClass == int.class || fieldClass == Integer.class) {
int intVal = lexer.scanFieldInt(name_chars);
if (intVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) {
fieldValue = null;
} else {
fieldValue = intVal;
} if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
// 如果找不到匹配信息,则跳过就好
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == long.class || fieldClass == Long.class) {
long longVal = lexer.scanFieldLong(name_chars);
if (longVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) {
fieldValue = null;
} else {
fieldValue = longVal;
} if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == String.class) {
// String 类型直接获取, "code" 字段获取
fieldValue = lexer.scanFieldString(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == java.util.Date.class && fieldInfo.format == null) {
fieldValue = lexer.scanFieldDate(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == BigDecimal.class) {
fieldValue = lexer.scanFieldDecimal(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == BigInteger.class) {
fieldValue = lexer.scanFieldBigInteger(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == boolean.class || fieldClass == Boolean.class) {
boolean booleanVal = lexer.scanFieldBoolean(name_chars); if (lexer.matchStat == JSONLexer.VALUE_NULL) {
fieldValue = null;
} else {
fieldValue = booleanVal;
} if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == float.class || fieldClass == Float.class) {
float floatVal = lexer.scanFieldFloat(name_chars);
if (floatVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) {
fieldValue = null;
} else {
fieldValue = floatVal;
} if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == double.class || fieldClass == Double.class) {
double doubleVal = lexer.scanFieldDouble(name_chars);
if (doubleVal == 0 && lexer.matchStat == JSONLexer.VALUE_NULL) {
fieldValue = null;
} else {
fieldValue = doubleVal;
} if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass.isEnum() //
&& parser.getConfig().getDeserializer(fieldClass) instanceof EnumDeserializer
&& (feildAnnotation == null || feildAnnotation.deserializeUsing() == Void.class)
) {
if (fieldDeser instanceof DefaultFieldDeserializer) {
ObjectDeserializer fieldValueDeserilizer = ((DefaultFieldDeserializer) fieldDeser).fieldValueDeserilizer;
fieldValue = this.scanEnum(lexer, name_chars, fieldValueDeserilizer); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
}
} else if (fieldClass == int[].class) {
fieldValue = lexer.scanFieldIntArray(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == float[].class) {
fieldValue = lexer.scanFieldFloatArray(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == float[][].class) {
fieldValue = lexer.scanFieldFloatArray2(name_chars); if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (lexer.matchField(name_chars)) {
matchField = true;
} else {
continue;
}
} if (!matchField) {
// 对于复杂泛型的解析,将从 symbolTable 中获取,该 symbolTable 中会以 orderId, name ... 形式呈现
key = lexer.scanSymbol(parser.symbolTable); if (key == null) {
token = lexer.token();
if (token == JSONToken.RBRACE) {
lexer.nextToken(JSONToken.COMMA);
break;
}
if (token == JSONToken.COMMA) {
if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
continue;
}
}
} if ("$ref" == key && context != null) {
lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
token = lexer.token();
if (token == JSONToken.LITERAL_STRING) {
String ref = lexer.stringVal();
if ("@".equals(ref)) {
object = context.object;
} else if ("..".equals(ref)) {
ParseContext parentContext = context.parent;
if (parentContext.object != null) {
object = parentContext.object;
} else {
parser.addResolveTask(new ResolveTask(parentContext, ref));
parser.resolveStatus = DefaultJSONParser.NeedToResolve;
}
} else if ("$".equals(ref)) {
ParseContext rootContext = context;
while (rootContext.parent != null) {
rootContext = rootContext.parent;
} if (rootContext.object != null) {
object = rootContext.object;
} else {
parser.addResolveTask(new ResolveTask(rootContext, ref));
parser.resolveStatus = DefaultJSONParser.NeedToResolve;
}
} else {
if (ref.indexOf('\\') > 0) {
StringBuilder buf = new StringBuilder();
for (int i = 0; i < ref.length(); ++i) {
char ch = ref.charAt(i);
if (ch == '\\') {
ch = ref.charAt(++i);
}
buf.append(ch);
}
ref = buf.toString();
}
Object refObj = parser.resolveReference(ref);
if (refObj != null) {
object = refObj;
} else {
parser.addResolveTask(new ResolveTask(context, ref));
parser.resolveStatus = DefaultJSONParser.NeedToResolve;
}
}
} else {
throw new JSONException("illegal ref, " + JSONToken.name(token));
} lexer.nextToken(JSONToken.RBRACE);
if (lexer.token() != JSONToken.RBRACE) {
throw new JSONException("illegal ref");
}
lexer.nextToken(JSONToken.COMMA); parser.setContext(context, object, fieldName); return (T) object;
} if ((typeKey != null && typeKey.equals(key))
|| JSON.DEFAULT_TYPE_KEY == key) {
lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
if (lexer.token() == JSONToken.LITERAL_STRING) {
String typeName = lexer.stringVal();
lexer.nextToken(JSONToken.COMMA); if (typeName.equals(beanInfo.typeName)|| parser.isEnabled(Feature.IgnoreAutoType)) {
if (lexer.token() == JSONToken.RBRACE) {
lexer.nextToken();
break;
}
continue;
} ObjectDeserializer deserializer = getSeeAlso(config, this.beanInfo, typeName);
Class<?> userType = null; if (deserializer == null) {
Class<?> expectClass = TypeUtils.getClass(type);
userType = config.checkAutoType(typeName, expectClass, lexer.getFeatures());
deserializer = parser.getConfig().getDeserializer(userType);
} Object typedObject = deserializer.deserialze(parser, userType, fieldName);
if (deserializer instanceof JavaBeanDeserializer) {
JavaBeanDeserializer javaBeanDeserializer = (JavaBeanDeserializer) deserializer;
if (typeKey != null) {
FieldDeserializer typeKeyFieldDeser = javaBeanDeserializer.getFieldDeserializer(typeKey);
typeKeyFieldDeser.setValue(typedObject, typeName);
}
}
return (T) typedObject;
} else {
throw new JSONException("syntax error");
}
}
} if (object == null && fieldValues == null) {
// 按照之前解析好的构造器,初始化一个实例,并作为返回的依据
// 找不到类型,则创建 HashMap, 所以 HashMap 是兜底数据结构
object = createInstance(parser, type);
if (object == null) {
fieldValues = new HashMap<String, Object>(this.fieldDeserializers.length);
}
childContext = parser.setContext(context, object, fieldName);
if (setFlags == null) {
// 32位一个标记位
setFlags = new int[(this.fieldDeserializers.length / 32) + 1];
}
} // 找到匹配后,解析
if (matchField) {
if (!valueParsed) {
fieldDeser.parseField(parser, object, type, fieldValues);
} else {
if (object == null) {
fieldValues.put(fieldInfo.name, fieldValue);
} else if (fieldValue == null) {
if (fieldClass != int.class //
&& fieldClass != long.class //
&& fieldClass != float.class //
&& fieldClass != double.class //
&& fieldClass != boolean.class //
) {
fieldDeser.setValue(object, fieldValue);
}
} else {
// 将解析出的值放入到 fieldDeser
// 使用反射写入 method.invoke(obj, value)
// fieldDeser 是对象的 一个字段描述
fieldDeser.setValue(object, fieldValue);
} if (setFlags != null) {
int flagIndex = fieldIndex / 32;
int bitIndex = fieldIndex % 32;
setFlags[flagIndex] |= (1 >> bitIndex);
} if (lexer.matchStat == JSONLexer.END) {
break;
}
}
} else {
// 如果没有匹配的话,就走字段解析,即递归操作
boolean match = parseField(parser, key, object, type, fieldValues, setFlags);
if (!match) {
if (lexer.token() == JSONToken.RBRACE) {
lexer.nextToken();
break;
} continue;
} else if (lexer.token() == JSONToken.COLON) {
throw new JSONException("syntax error, unexpect token ':'");
}
} // 为下一个字段解析做准备
if (lexer.token() == JSONToken.COMMA) {
continue;
} if (lexer.token() == JSONToken.RBRACE) {
lexer.nextToken(JSONToken.COMMA);
break;
} if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) {
throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token()));
}
} // 至此fastjson 解析就完成了
if (object == null) {
if (fieldValues == null) {
object = createInstance(parser, type);
if (childContext == null) {
childContext = parser.setContext(context, object, fieldName);
}
return (T) object;
} String[] paramNames = beanInfo.creatorConstructorParameters;
final Object[] params;
if (paramNames != null) {
params = new Object[paramNames.length];
for (int i = 0; i < paramNames.length; i++) {
String paramName = paramNames[i]; Object param = fieldValues.remove(paramName);
if (param == null) {
Type fieldType = beanInfo.creatorConstructorParameterTypes[i];
FieldInfo fieldInfo = beanInfo.fields[i];
if (fieldType == byte.class) {
param = (byte) 0;
} else if (fieldType == short.class) {
param = (short) 0;
} else if (fieldType == int.class) {
param = 0;
} else if (fieldType == long.class) {
param = 0L;
} else if (fieldType == float.class) {
param = 0F;
} else if (fieldType == double.class) {
param = 0D;
} else if (fieldType == boolean.class) {
param = Boolean.FALSE;
} else if (fieldType == String.class
&& (fieldInfo.parserFeatures & Feature.InitStringFieldAsEmpty.mask) != 0) {
param = "";
}
} else {
if (beanInfo.creatorConstructorParameterTypes != null && i < beanInfo.creatorConstructorParameterTypes.length) {
Type paramType = beanInfo.creatorConstructorParameterTypes[i];
if (paramType instanceof Class) {
Class paramClass = (Class) paramType;
if (!paramClass.isInstance(param)) {
if (param instanceof List) {
List list = (List) param;
if (list.size() == 1) {
Object first = list.get(0);
if (paramClass.isInstance(first)) {
param = list.get(0);
}
}
}
}
}
}
}
params[i] = param;
}
} else {
FieldInfo[] fieldInfoList = beanInfo.fields;
int size = fieldInfoList.length;
params = new Object[size];
for (int i = 0; i < size; ++i) {
FieldInfo fieldInfo = fieldInfoList[i];
Object param = fieldValues.get(fieldInfo.name);
if (param == null) {
Type fieldType = fieldInfo.fieldType;
if (fieldType == byte.class) {
param = (byte) 0;
} else if (fieldType == short.class) {
param = (short) 0;
} else if (fieldType == int.class) {
param = 0;
} else if (fieldType == long.class) {
param = 0L;
} else if (fieldType == float.class) {
param = 0F;
} else if (fieldType == double.class) {
param = 0D;
} else if (fieldType == boolean.class) {
param = Boolean.FALSE;
} else if (fieldType == String.class
&& (fieldInfo.parserFeatures & Feature.InitStringFieldAsEmpty.mask) != 0) {
param = "";
}
}
params[i] = param;
}
} if (beanInfo.creatorConstructor != null) {
boolean hasNull = false;
if (beanInfo.kotlin) {
for (int i = 0; i < params.length; i++) {
if (params[i] == null && beanInfo.fields != null && i < beanInfo.fields.length) {
FieldInfo fieldInfo = beanInfo.fields[i];
if (fieldInfo.fieldClass == String.class) {
hasNull = true;
}
break;
}
}
} try {
if (hasNull && beanInfo.kotlinDefaultConstructor != null) {
object = beanInfo.kotlinDefaultConstructor.newInstance(new Object[0]); for (int i = 0; i < params.length; i++) {
final Object param = params[i];
if (param != null && beanInfo.fields != null && i < beanInfo.fields.length) {
FieldInfo fieldInfo = beanInfo.fields[i];
fieldInfo.set(object, param);
}
}
} else {
object = beanInfo.creatorConstructor.newInstance(params);
}
} catch (Exception e) {
throw new JSONException("create instance error, " + paramNames + ", "
+ beanInfo.creatorConstructor.toGenericString(), e);
} if (paramNames != null) {
for (Map.Entry<String, Object> entry : fieldValues.entrySet()) {
FieldDeserializer fieldDeserializer = getFieldDeserializer(entry.getKey());
if (fieldDeserializer != null) {
fieldDeserializer.setValue(object, entry.getValue());
}
}
}
} else if (beanInfo.factoryMethod != null) {
try {
object = beanInfo.factoryMethod.invoke(null, params);
} catch (Exception e) {
throw new JSONException("create factory method error, " + beanInfo.factoryMethod.toString(), e);
}
} childContext.object = object;
}
// 还可以再用 buildMethod 再修饰一翻, 如果有设置的话
Method buildMethod = beanInfo.buildMethod;
if (buildMethod == null) {
// 因创建时就是 T 类型,所以这里直接强转
return (T) object;
} Object builtObj;
try {
builtObj = buildMethod.invoke(object);
} catch (Exception e) {
throw new JSONException("build object error", e);
} return (T) builtObj;
} finally {
if (childContext != null) {
childContext.object = object;
}
parser.setContext(context);
}
} // 解析字段值
public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType,
Map<String, Object> fieldValues, int[] setFlags) {
JSONLexer lexer = parser.lexer; // xxx final int disableFieldSmartMatchMask = Feature.DisableFieldSmartMatch.mask;
FieldDeserializer fieldDeserializer;
if (lexer.isEnabled(disableFieldSmartMatchMask) || (this.beanInfo.parserFeatures & disableFieldSmartMatchMask) != 0) {
fieldDeserializer = getFieldDeserializer(key);
} else {
fieldDeserializer = smartMatch(key, setFlags);
} final int mask = Feature.SupportNonPublicField.mask;
if (fieldDeserializer == null
&& (lexer.isEnabled(mask)
|| (this.beanInfo.parserFeatures & mask) != 0)) {
if (this.extraFieldDeserializers == null) {
ConcurrentHashMap extraFieldDeserializers = new ConcurrentHashMap<String, Object>(1, 0.75f, 1);
for (Class c = this.clazz; c != null && c != Object.class; c = c.getSuperclass()) {
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
if (this.getFieldDeserializer(fieldName) != null) {
continue;
}
int fieldModifiers = field.getModifiers();
if ((fieldModifiers & Modifier.FINAL) != 0 || (fieldModifiers & Modifier.STATIC) != 0) {
continue;
}
extraFieldDeserializers.put(fieldName, field);
}
}
this.extraFieldDeserializers = extraFieldDeserializers;
} Object deserOrField = extraFieldDeserializers.get(key);
if (deserOrField != null) {
if (deserOrField instanceof FieldDeserializer) {
fieldDeserializer = ((FieldDeserializer) deserOrField);
} else {
Field field = (Field) deserOrField;
field.setAccessible(true);
FieldInfo fieldInfo = new FieldInfo(key, field.getDeclaringClass(), field.getType(), field.getGenericType(), field, 0, 0, 0);
fieldDeserializer = new DefaultFieldDeserializer(parser.getConfig(), clazz, fieldInfo);
extraFieldDeserializers.put(key, fieldDeserializer);
}
}
} if (fieldDeserializer == null) {
if (!lexer.isEnabled(Feature.IgnoreNotMatch)) {
throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
} for (FieldDeserializer fieldDeser : this.sortedFieldDeserializers) {
FieldInfo fieldInfo = fieldDeser.fieldInfo;
if (fieldInfo.unwrapped //
&& fieldDeser instanceof DefaultFieldDeserializer) {
if (fieldInfo.field != null) {
DefaultFieldDeserializer defaultFieldDeserializer = (DefaultFieldDeserializer) fieldDeser;
ObjectDeserializer fieldValueDeser = defaultFieldDeserializer.getFieldValueDeserilizer(parser.getConfig());
if (fieldValueDeser instanceof JavaBeanDeserializer) {
JavaBeanDeserializer javaBeanFieldValueDeserializer = (JavaBeanDeserializer) fieldValueDeser;
FieldDeserializer unwrappedFieldDeser = javaBeanFieldValueDeserializer.getFieldDeserializer(key);
if (unwrappedFieldDeser != null) {
Object fieldObject;
try {
fieldObject = fieldInfo.field.get(object);
if (fieldObject == null) {
fieldObject = ((JavaBeanDeserializer) fieldValueDeser).createInstance(parser, fieldInfo.fieldType);
fieldDeser.setValue(object, fieldObject);
}
lexer.nextTokenWithColon(defaultFieldDeserializer.getFastMatchToken());
unwrappedFieldDeser.parseField(parser, fieldObject, objectType, fieldValues);
return true;
} catch (Exception e) {
throw new JSONException("parse unwrapped field error.", e);
}
}
} else if (fieldValueDeser instanceof MapDeserializer) {
MapDeserializer javaBeanFieldValueDeserializer = (MapDeserializer) fieldValueDeser; Map fieldObject;
try {
fieldObject = (Map) fieldInfo.field.get(object);
if (fieldObject == null) {
fieldObject = javaBeanFieldValueDeserializer.createMap(fieldInfo.fieldType);
fieldDeser.setValue(object, fieldObject);
} lexer.nextTokenWithColon();
Object fieldValue = parser.parse(key);
fieldObject.put(key, fieldValue);
} catch (Exception e) {
throw new JSONException("parse unwrapped field error.", e);
}
return true;
}
} else if (fieldInfo.method.getParameterTypes().length == 2) {
lexer.nextTokenWithColon();
Object fieldValue = parser.parse(key);
try {
fieldInfo.method.invoke(object, key, fieldValue);
} catch (Exception e) {
throw new JSONException("parse unwrapped field error.", e);
}
return true;
}
}
} parser.parseExtra(object, key); return false;
} int fieldIndex = -1;
for (int i = 0; i < sortedFieldDeserializers.length; ++i) {
if (sortedFieldDeserializers[i] == fieldDeserializer) {
fieldIndex = i;
break;
}
}
if (fieldIndex != -1 && setFlags != null && key.startsWith("_")) {
if (isSetFlag(fieldIndex, setFlags)) {
parser.parseExtra(object, key);
return false;
}
} lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken()); // 调用 deserializer.parseField()
fieldDeserializer.parseField(parser, object, objectType, fieldValues); return true;
} // com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer
@Override
public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) {
if (this.fieldValueDeserilizer == null) {
getFieldValueDeserilizer(parser.getConfig());
} ObjectDeserializer fieldValueDeserilizer = this.fieldValueDeserilizer;
Type fieldType = fieldInfo.fieldType;
if (objectType instanceof ParameterizedType) {
ParseContext objContext = parser.getContext();
if (objContext != null) {
objContext.type = objectType;
}
if (fieldType != objectType) {
fieldType = FieldInfo.getFieldType(this.clazz, objectType, fieldType);
fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType);
}
} // ContextObjectDeserializer
Object value;
if (fieldValueDeserilizer instanceof JavaBeanDeserializer && fieldInfo.parserFeatures != 0) {
JavaBeanDeserializer javaBeanDeser = (JavaBeanDeserializer) fieldValueDeserilizer;
value = javaBeanDeser.deserialze(parser, fieldType, fieldInfo.name, fieldInfo.parserFeatures);
} else {
if (this.fieldInfo.format != null && fieldValueDeserilizer instanceof ContextObjectDeserializer) {
value = ((ContextObjectDeserializer) fieldValueDeserilizer) //
.deserialze(parser,
fieldType,
fieldInfo.name,
fieldInfo.format,
fieldInfo.parserFeatures);
} else {
value = fieldValueDeserilizer.deserialze(parser, fieldType, fieldInfo.name);
}
} if (value instanceof byte[]
&& ("gzip".equals(fieldInfo.format) || "gzip,base64".equals(fieldInfo.format))) {
byte[] bytes = (byte[]) value;
GZIPInputStream gzipIn = null;
try {
gzipIn = new GZIPInputStream(new ByteArrayInputStream(bytes)); ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
for (;;) {
byte[] buf = new byte[1024];
int len = gzipIn.read(buf);
if (len == -1) {
break;
}
if (len > 0) {
byteOut.write(buf, 0, len);
}
}
value = byteOut.toByteArray(); } catch (IOException ex) {
throw new JSONException("unzip bytes error.", ex);
}
} if (parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) {
ResolveTask task = parser.getLastResolveTask();
task.fieldDeserializer = this;
task.ownerContext = parser.getContext();
parser.setResolveStatus(DefaultJSONParser.NONE);
} else {
if (object == null) {
fieldValues.put(fieldInfo.name, value);
} else {
// 将解析出的字段值放入原对象中, 即 ResponseEntity
// 此处的字段信息已已知,所以只需要将对象传入即可, fieldInfo.method
setValue(object, value);
}
}
} // com.alibaba.fastjson.parser.deserializer.MapDeserializer
@SuppressWarnings("unchecked")
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
if (type == JSONObject.class && parser.getFieldTypeResolver() == null) {
return (T) parser.parseObject();
} final JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.NULL) {
lexer.nextToken(JSONToken.COMMA);
return null;
} // 创建空map
Map<Object, Object> map = createMap(type); ParseContext context = parser.getContext(); try {
parser.setContext(context, map, fieldName);
return (T) deserialze(parser, type, fieldName, map);
} finally {
parser.setContext(context);
}
} @SuppressWarnings({ "unchecked", "rawtypes" })
public Map<Object, Object> createMap(Type type) {
if (type == Properties.class) {
return new Properties();
} if (type == Hashtable.class) {
return new Hashtable();
} if (type == IdentityHashMap.class) {
return new IdentityHashMap();
} if (type == SortedMap.class || type == TreeMap.class) {
return new TreeMap();
} if (type == ConcurrentMap.class || type == ConcurrentHashMap.class) {
return new ConcurrentHashMap();
} if (type == Map.class || type == HashMap.class) {
return new HashMap();
} if (type == LinkedHashMap.class) {
return new LinkedHashMap();
} if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type; Type rawType = parameterizedType.getRawType();
if (EnumMap.class.equals(rawType)) {
Type[] actualArgs = parameterizedType.getActualTypeArguments();
return new EnumMap((Class) actualArgs[0]);
}
// 通用map再递归创建, 其实就是创建一个 HashMap
return createMap(rawType);
} Class<?> clazz = (Class<?>) type;
if (clazz.isInterface()) {
throw new JSONException("unsupport type " + type);
} try {
return (Map<Object, Object>) clazz.newInstance();
} catch (Exception e) {
throw new JSONException("unsupport type " + type, e);
}
} // 最后,来看 map 是如何解析的吧:分两步, 1. key 的解析; 2. value 的解析
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, Map map) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// key 的类型取第一个 type
Type keyType = parameterizedType.getActualTypeArguments()[0];
Type valueType = null;
if(map.getClass().getName().equals("org.springframework.util.LinkedMultiValueMap")){
valueType = List.class;
}else{
// value 的类型取第二个 type
valueType = parameterizedType.getActualTypeArguments()[1];
}
// 到此,整个 泛型的推导就完成了,后面就是对值的解析了
if (String.class == keyType) {
return parseMap(parser, (Map<String, Object>) map, valueType, fieldName);
} else {
return parseMap(parser, map, keyType, valueType, fieldName);
}
} else {
return parser.parseObject(map, fieldName);
}
} @SuppressWarnings("rawtypes")
public static Map parseMap(DefaultJSONParser parser, Map<String, Object> map, Type valueType, Object fieldName) {
JSONLexer lexer = parser.lexer; int token = lexer.token();
if (token != JSONToken.LBRACE) {
String msg = "syntax error, expect {, actual " + lexer.tokenName();
if (fieldName instanceof String) {
msg += ", fieldName ";
msg += fieldName;
}
msg += ", ";
msg += lexer.info(); if (token != JSONToken.LITERAL_STRING) {
JSONArray array = new JSONArray();
parser.parseArray(array, fieldName); if (array.size() == 1) {
Object first = array.get(0);
if (first instanceof JSONObject) {
return (JSONObject) first;
}
}
} throw new JSONException(msg);
} ParseContext context = parser.getContext();
try {
for (int i = 0;;++i) {
lexer.skipWhitespace();
char ch = lexer.getCurrent();
if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
while (ch == ',') {
lexer.next();
lexer.skipWhitespace();
ch = lexer.getCurrent();
}
} String key;
if (ch == '"') {
// 按 '"' 进行分隔,得出第一个 key, 即 orderId
key = lexer.scanSymbol(parser.getSymbolTable(), '"');
lexer.skipWhitespace();
ch = lexer.getCurrent();
if (ch != ':') {
throw new JSONException("expect ':' at " + lexer.pos());
}
} else if (ch == '}') {
lexer.next();
lexer.resetStringPosition();
lexer.nextToken(JSONToken.COMMA);
return map;
} else if (ch == '\'') {
if (!lexer.isEnabled(Feature.AllowSingleQuotes)) {
throw new JSONException("syntax error");
} key = lexer.scanSymbol(parser.getSymbolTable(), '\'');
lexer.skipWhitespace();
ch = lexer.getCurrent();
if (ch != ':') {
throw new JSONException("expect ':' at " + lexer.pos());
}
} else {
if (!lexer.isEnabled(Feature.AllowUnQuotedFieldNames)) {
throw new JSONException("syntax error");
} key = lexer.scanSymbolUnQuoted(parser.getSymbolTable());
lexer.skipWhitespace();
ch = lexer.getCurrent();
if (ch != ':') {
throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch);
}
} // key 解析完成后,解析下一个
lexer.next();
lexer.skipWhitespace();
ch = lexer.getCurrent(); // 重置解析开始
lexer.resetStringPosition(); if (key == JSON.DEFAULT_TYPE_KEY && !lexer.isEnabled(Feature.DisableSpecialKeyDetect)) {
String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"');
final ParserConfig config = parser.getConfig(); Class<?> clazz = config.checkAutoType(typeName, null, lexer.getFeatures()); if (Map.class.isAssignableFrom(clazz) ) {
lexer.nextToken(JSONToken.COMMA);
if (lexer.token() == JSONToken.RBRACE) {
lexer.nextToken(JSONToken.COMMA);
return map;
}
continue;
} ObjectDeserializer deserializer = config.getDeserializer(clazz); lexer.nextToken(JSONToken.COMMA); parser.setResolveStatus(DefaultJSONParser.TypeNameRedirect); if (context != null && !(fieldName instanceof Integer)) {
parser.popContext();
} return (Map) deserializer.deserialze(parser, clazz, fieldName);
} Object value;
lexer.nextToken(); if (i != 0) {
parser.setContext(context);
} if (lexer.token() == JSONToken.NULL) {
value = null;
lexer.nextToken();
} else {
value = parser.parseObject(valueType, key);
} // 是否需要 ResolveFieldDeserializer 处理一遍
map.put(key, value);
parser.checkMapResolve(map, key); parser.setContext(context, value, key);
parser.setContext(context); final int tok = lexer.token();
if (tok == JSONToken.EOF || tok == JSONToken.RBRACKET) {
return map;
} if (tok == JSONToken.RBRACE) {
// 解析完成
lexer.nextToken();
return map;
}
}
} finally {
parser.setContext(context);
} } // com.alibaba.fastjson.parser.JSONLexerBase
public final String scanSymbol(final SymbolTable symbolTable, final char quote) {
int hash = 0; np = bp;
sp = 0;
boolean hasSpecial = false;
char chLocal;
for (;;) {
chLocal = next(); // 遇到下一个分符则停止, 转义符除外
if (chLocal == quote) {
break;
} if (chLocal == EOI) {
throw new JSONException("unclosed.str");
} // 遇到转义符时,会向后推进一位判定
if (chLocal == '\\') {
if (!hasSpecial) {
hasSpecial = true; if (sp >= sbuf.length) {
int newCapcity = sbuf.length * 2;
if (sp > newCapcity) {
newCapcity = sp;
}
char[] newsbuf = new char[newCapcity];
System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length);
sbuf = newsbuf;
} // text.getChars(np + 1, np + 1 + sp, sbuf, 0);
// System.arraycopy(this.buf, np + 1, sbuf, 0, sp);
arrayCopy(np + 1, sbuf, 0, sp);
} chLocal = next(); switch (chLocal) {
case '0':
hash = 31 * hash + (int) chLocal;
putChar('\0');
break;
case '1':
hash = 31 * hash + (int) chLocal;
putChar('\1');
break;
case '2':
hash = 31 * hash + (int) chLocal;
putChar('\2');
break;
case '3':
hash = 31 * hash + (int) chLocal;
putChar('\3');
break;
case '4':
hash = 31 * hash + (int) chLocal;
putChar('\4');
break;
case '5':
hash = 31 * hash + (int) chLocal;
putChar('\5');
break;
case '6':
hash = 31 * hash + (int) chLocal;
putChar('\6');
break;
case '7':
hash = 31 * hash + (int) chLocal;
putChar('\7');
break;
case 'b': //
hash = 31 * hash + (int) '\b';
putChar('\b');
break;
case 't': //
hash = 31 * hash + (int) '\t';
putChar('\t');
break;
case 'n': //
hash = 31 * hash + (int) '\n';
putChar('\n');
break;
case 'v': //
hash = 31 * hash + (int) '\u000B';
putChar('\u000B');
break;
case 'f': //
case 'F':
hash = 31 * hash + (int) '\f';
putChar('\f');
break;
case 'r': //
hash = 31 * hash + (int) '\r';
putChar('\r');
break;
case '"': //
hash = 31 * hash + (int) '"';
putChar('"');
break;
case '\'': //
hash = 31 * hash + (int) '\'';
putChar('\'');
break;
case '/': //
hash = 31 * hash + (int) '/';
putChar('/');
break;
case '\\': //
hash = 31 * hash + (int) '\\';
putChar('\\');
break;
// 16进制数据
case 'x':
char x1 = ch = next();
char x2 = ch = next(); int x_val = digits[x1] * 16 + digits[x2];
char x_char = (char) x_val;
hash = 31 * hash + (int) x_char;
putChar(x_char);
break;
// unicode 编码
case 'u':
char c1 = chLocal = next();
char c2 = chLocal = next();
char c3 = chLocal = next();
char c4 = chLocal = next();
int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16);
hash = 31 * hash + val;
putChar((char) val);
break;
default:
this.ch = chLocal;
throw new JSONException("unclosed.str.lit");
}
continue;
} hash = 31 * hash + chLocal; if (!hasSpecial) {
sp++;
continue;
} if (sp == sbuf.length) {
putChar(chLocal);
} else {
sbuf[sp++] = chLocal;
}
} token = LITERAL_STRING; String value;
if (!hasSpecial) {
// return this.text.substring(np + 1, np + 1 + sp).intern();
int offset;
if (np == -1) {
offset = 0;
} else {
// 向后推进计算位
offset = np + 1;
}
// 取出相应value
value = addSymbol(offset, sp, hash, symbolTable);
} else {
value = symbolTable.addSymbol(sbuf, 0, sp, hash);
} // 解析下一个做准备, ':' 分隔符跳过
sp = 0;
this.next(); return value;
} public final String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable) {
return symbolTable.addSymbol(text, offset, len, hash);
}
// com.alibaba.fastjson.parser.SymbolTable
public String addSymbol(String buffer, int offset, int len, int hash) {
return addSymbol(buffer, offset, len, hash, false);
} public String addSymbol(String buffer, int offset, int len, int hash, boolean replace) {
// 根据 hash 定位value,
final int bucket = hash & indexMask; String symbol = symbols[bucket];
if (symbol != null) {
if (hash == symbol.hashCode() //
&& len == symbol.length() //
&& buffer.startsWith(symbol, offset)) {
return symbol;
} String str = subString(buffer, offset, len); if (replace) {
symbols[bucket] = str;
} return str;
} symbol = len == buffer.length() //
? buffer //
: subString(buffer, offset, len);
symbol = symbol.intern();
// 没有解析出则现在存入 symbols
symbols[bucket] = symbol;
return symbol;
}
总结: 泛型推断其实很简单:
1. 普通泛型会被jdk封装为 TypeVariableImpl, 而复合泛型则会被封装为 ParameterizedTypeImpl;
2. 通过 Class.getGenericSuperclass(), 可以获取完整泛型信息类;
3. 通过 (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0] 可以获取完整泛型;
4. 通过 ParameterizedType.getRawType() 获取运行时的类信息;
5. 通过 ParameterizedType.getActualTypeArguments() 获取泛型的内部信息;
6. 对于多泛型传递导致的类型丢失,在 TypeReference 构造函数传入原始信息,进行对应还原即可;
7. 当然本文说了很多其他废话;(json的解析过程)
从fastjson多层泛型嵌套解析,看jdk泛型推断的更多相关文章
- 一点一点看JDK源码(三)java.util.ArrayList 前偏
一点一点看JDK源码(三)java.util.ArrayList liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 ArrayLi ...
- 一点一点看JDK源码(一)Collection体系概览
一点一点看JDK源码(一)Collection体系概览 liuyuhang原创,未经允许进制转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 Collection为集 ...
- JDK 泛型之 Type
JDK 泛型之 Type 一.Type 接口 JDK 1.5 引入 Type,主要是为了泛型,没有泛型的之前,只有所谓的原始类型.此时,所有的原始类型都通过字节码文件类 Class 类进行抽象.Cla ...
- 一点一点看JDK源码(二)java.util.List
一点一点看JDK源码(二)java.util.List liuyuhang原创,未经允许进制转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 List译为表,一览表, ...
- 一点一点看JDK源码(四)java.util.ArrayList 中篇
一点一点看JDK源码(四)java.util.ArrayList 中篇 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 在前篇中 ...
- (1)消灭初级程序员常用的多层if-else嵌套--------------【表驱动法】
表驱动法 1.相信很多刚从事工作的程序员或一些初级程序员在写代码的时候会出现对一些逻辑判断写成多层if-else嵌套的经历,这种方式在一些简单的层次中运用起来确实可行,但对于一些大型项目逻辑判断比较多 ...
- .net中的泛型全面解析
从2.0起我们一直就在谈论泛型,那么什么是泛型,泛型有什么好处,与泛型相关的概念又该怎么使用,比如泛型方法,泛型委托.这一篇我会全面的介绍泛型. 那么首先我们必须搞清楚什么是泛型,泛型其实也是一种类型 ...
- Android JSON、GSON、FastJson的封装与解析
声明: 1.本帖只提供代码,不深入讲解原理.如果读者想要深入了解,那就不要在这个帖子上浪费时间了 2.客户端用的是Google官方的Volley访问服务器,具体了解Volley请戳 这里 3.本帖三种 ...
- java泛型---通配符,泛型嵌套
package generic; import java.util.ArrayList; import java.util.List; /** * ? -->通配符,类型不确定,用于声明 变量| ...
随机推荐
- 部署:持续集成(CI)与持续交付(CD)——《微服务设计》读书笔记
系列文章目录: <微服务设计>读书笔记大纲 一.CI(Continuous Integration)简介 CI规则1:尽量频繁地把代码签入到分支中以进行集成 CI规则2: ...
- javaweb项目部署到tomcat服务器
http://jingyan.baidu.com/album/a501d80c0c65baec630f5ef6.html?picindex=8
- CORS(跨域资源共享) 的配置
http://blog.csdn.net/ohyoyo2014/article/details/24863197 兼容情况: 各种新版本的ie10,firefox,opera,safari,chrom ...
- Python爬虫-pyspider框架的使用
pyspider 是一个用python实现的功能强大的网络爬虫系统,能在浏览器界面上进行脚本的编写,功能的调度和爬取结果的实时查看,后端使用常用的数据库进行爬取结果的存储,还能定时设置任务与任务优 ...
- dqname.go
package nsqd func getBackendName(topicName, channelName string) string { // backend names, for u ...
- 【Unity游戏开发】AssetBundle杂记--AssetBundle的二三事
一.简介 马三在公司大部分时间做的都是游戏业务逻辑和编辑器工具等相关工作,因此对Unity AssetBundle这块的知识点并不是很熟悉,自己也是有打算想了解并熟悉一下AssetBundle,掌握一 ...
- Spring IOC(三)依赖注入
本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 1.AbstractBeanFactory ...
- linux清除全屏快捷键(Ctrl+L)
Linux用户基本上都习惯使用clear命令或Ctrl+L组合快捷键来清空终端屏幕.这样做其实并没有真正地清空屏幕,但当用鼠标向上滚时,你仍然能看到之前的命令操作留下来的输出.
- SQL数据库的一些操作
--以 MySQL为例 //登陆 mysql -u root -p //创建一个名为test_lib的数据库 CREATE DATABASE test_lib //删除一个名为test_lib的数据库 ...
- python 安装cv2
问题描述:import cv2 报错提示未安装此包. 解决措施: 1.cmd框中输入pip install cv2,若安装成功,则恭喜你一次性成功,如提示"无法找到与你当前版本的匹配&quo ...