从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就不用写了吧!

其实做这一步的解析,还是容易的。不过,具体怎么做,就不一定了。网址:yii666.com<

  另一个问题,解析这些数据结构,我需要再封装得简单点,因为底层的数据访问步骤都是一样的,我不想重复造轮子!比如,我只需要在最上层转入想要转化的数据结构类型,就可以得到不一样的数据对象!

这个当然很简单,只需要使用泛型方法就行了。简单示例如下:文章地址https://www.yii666.com/article/754287.html

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,这其实不重要。文章来源地址:https://www.yii666.com/article/754287.html

  重要的是,你认为,如上代码能成功达到要求吗???

  不管怎么样,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, 实际在运行时已经不在了!网址:yii666.com

  所以,第二次封装后,只剩下了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&lt;List&lt;String&gt;&gt; list = new TypeReference&lt;List&lt;String&gt;&gt;() {};
* </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&lt;Model&gt; models = JSON.parseObject(jsonStr, new TypeReference&lt;List&lt;Model&gt;&gt;() {});
* </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.
}

解析文章来源地址https://www.yii666.com/article/754287.html

    // 获取到 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泛型推断-相关文章

  1. 记 fastjson泛型转对象 第一次可以正常转,第二次就变成JSONArray 问题

  2. 从fastjson多层泛型嵌套解析,看jdk泛型推断

  3. C#泛型序列化困境

  4. 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的

    数组和泛型容器有什么区别要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance)、逆变性(contravariance)和无关性(invariant)。若类A是类B的子类,则记作A ≦ B。设有变换f(),若:在Java中,数组具有协变性,而泛型具有无关性,示例代码如下:这两句代

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信图片_20190322181744_03.jpg

微信扫一扫打赏

请作者喝杯咖啡吧~

支付宝扫一扫领取红包,优惠每天领

二维码1

zhifubaohongbao.png

二维码2

zhifubaohongbao2.png