fastjson序列化和反序列化

1. 对象和Json字符串之间的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package example;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class doJson {

static String Object2Json(Object obj, SerializerFeature serializerFeature){
String jsonStr = JSON.toJSONString(obj, serializerFeature);
return jsonStr;
}

static Object Json2Object(String jsonStr){
Object o = JSON.parse(jsonStr);
return o;
}

public static void main(String[] args) {
User user = new User();
String str = Object2Json(user, SerializerFeature.WriteNullNumberAsZero);
System.out.println("User对象没有赋值转换为Json字符串:");
System.out.println(str);
System.out.println(JSON.toJSONString(user));
user.setName("Lion");
user.setAge(18);
user.setSchool("qinghua");
System.out.println("User对象字段赋值后转换为Json字符串:");
System.out.println(Object2Json(user, SerializerFeature.WriteNullNumberAsZero));
System.out.println("指定类后转换为Json字符串");
System.out.println(Object2Json(user, SerializerFeature.WriteClassName));
}
}
1 2

2. 反序列化解析流程

这里主要看一下字符串转成Object的解析流程

2.1 创建JSON解析器

com.alibaba.fastjson.parse

  1. 创建默认的JSON解析器,默认的全局配置中有DenyList,1.2.24版本上只有两个Thread类
3
  1. 创建新的Json解析器中,跟入new JSONScanner(intput, features)
4
  1. 进入JSONScanner的构造方法,这里去了字符串的第一个字符,如{,判断了是否为\ufeff(Byte Order Mark,字节顺序标记,出现在文本文件头部,Unicode编码标准中用于标识文件是采用哪种格式的编码)
5
  1. 进入DefaultJSONParser构造方法

可以看到判断第一个字符是否为{如果是则取下一个字符,下面有个判断是否为[的,这个可以留着再分析 ,此时的token被指定为12

6

2.2 解析器工作

  • parse.parse()解析

回到步骤1,进入parse.parse();首先判断Token是否正常,1,5,10,11,13,15,16,17,18,19都会抛出异常,这里感觉有很多的case分支,不知道的干什么的,也可以留下来

7
7
  1. 进入com.alibaba.fastjson.parser.DefaultJSONParser#parseObject
9

第一步跳过空白字符,跟入方法看见 首先判断ch是否<='/',然后 \r\n\t\f\b,如果等于/;循环判断是否为/*\n

10
如图会取Key值,即`""`中的字符,如`@type`
10
继续向下,判断Key是否为@type后,以"为单位获取对应的`Class`,ClassLoader为`this.config.getDefaultClassLoader`,此时为null
12

2.2.1 @type类加载

这里首先通过mapping去直接获取Class,如果不是这些开头的key,则继续运行

13
如代码分析,有几个判断条件,首先判断第一个字符是否为`[`,其次判断是否为`L`且结束为`;`
  • [时,通过loadClass加载[后的字符,并返回Array动态数组
  • L开头时,去中间字符串类名,再次调用loadClass进行加载

接下来判断ClassLoader是否为空

  • 如果为空则取Thread.currentThread().getContextClassLoader()

  • 如果取Class失败,直接通过Class.forName获取类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public static Class<?> loadClass(String className, ClassLoader classLoader) {
    if (className != null && className.length() != 0) {
    Class<?> clazz = (Class)mappings.get(className);
    if (clazz != null) {
    return clazz;
    } else if (className.charAt(0) == '[') {
    Class<?> componentType = loadClass(className.substring(1), classLoader);
    return Array.newInstance(componentType, 0).getClass();
    } else if (className.startsWith("L") && className.endsWith(";")) {
    String newClassName = className.substring(1, className.length() - 1);
    return loadClass(newClassName, classLoader);
    } else {
    try {
    if (classLoader != null) {
    clazz = classLoader.loadClass(className);
    mappings.put(className, clazz);
    return clazz;
    }
    } catch (Throwable var6) {
    var6.printStackTrace();
    }

    try {
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    if (contextClassLoader != null) {
    clazz = contextClassLoader.loadClass(className);
    mappings.put(className, clazz);
    return clazz;
    }
    } catch (Throwable var5) {
    }

    try {
    clazz = Class.forName(className);
    mappings.put(className, clazz);
    return clazz;
    } catch (Throwable var4) {
    return clazz;
    }
    }
    } else {
    return null;
    }
    }

    2.2.2 类加载成功后

    这里会执行nextToken,先看看nextToken是什么,如果token=13,则进入一段执行代码,通过查看nextToken中代码,发现ch=}时会导致token=13

  • 这里先跳过他,如果是}的话,大概逻辑也就是实例化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    if (lexer.token() == 13) {
    lexer.nextToken(16);

    try {
    instance = null;
    ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
    if (deserializer instanceof JavaBeanDeserializer) {
    instance = ((JavaBeanDeserializer)deserializer).createInstance(this, clazz);
    }

    if (instance == null) {
    if (clazz == Cloneable.class) {
    instance = new HashMap();
    } else if ("java.util.Collections$EmptyMap".equals(ref)) {
    instance = Collections.emptyMap();
    } else {
    instance = clazz.newInstance();
    }
    }

    obj = instance;
    return obj;
    } catch (Exception var23) {
    throw new JSONException("create instance error", var23);
    }
    }
    14
1
ObjectDeserializer deserializer = this.config.getDeserializer(clazz);

查看这个方法,判断type是否是Class类型、ParameterizedType类型

1
2
3
4
5
6
7
8
9
10
11
12
13
public ObjectDeserializer getDeserializer(Type type) {
ObjectDeserializer derializer = (ObjectDeserializer)this.derializers.get(type);
if (derializer != null) {
return derializer;
} else if (type instanceof Class) {
return this.getDeserializer((Class)type, type);
} else if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType)type).getRawType();
return rawType instanceof Class ? this.getDeserializer((Class)rawType, type) : this.getDeserializer(rawType);
} else {
return JavaObjectDeserializer.instance;
}
}

2.2.3 获取反序列化工具类

getDeserializer方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
ObjectDeserializer derializer = (ObjectDeserializer)this.derializers.get(type);
if (derializer != null) {
return derializer;
} else {
if (type == null) {
type = clazz;
}

ObjectDeserializer derializer = (ObjectDeserializer)this.derializers.get(type);
if (derializer != null) {
return (ObjectDeserializer)derializer;
} else {
JSONType annotation = (JSONType)clazz.getAnnotation(JSONType.class);
if (annotation != null) {
Class<?> mappingTo = annotation.mappingTo();
if (mappingTo != Void.class) {
return this.getDeserializer(mappingTo, mappingTo);
}
}

if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
derializer = (ObjectDeserializer)this.derializers.get(clazz);
}

if (derializer != null) {
return (ObjectDeserializer)derializer;
} else {
String className = clazz.getName();
className = className.replace('$', '.');

for(int i = 0; i < this.denyList.length; ++i) {
String deny = this.denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("parser deny : " + className);
}
}

if (className.startsWith("java.awt.") && AwtCodec.support(clazz) && !awtError) {
try {
this.derializers.put(Class.forName("java.awt.Point"), AwtCodec.instance);
this.derializers.put(Class.forName("java.awt.Font"), AwtCodec.instance);
this.derializers.put(Class.forName("java.awt.Rectangle"), AwtCodec.instance);
this.derializers.put(Class.forName("java.awt.Color"), AwtCodec.instance);
} catch (Throwable var11) {
awtError = true;
}

derializer = AwtCodec.instance;
}

if (!jdk8Error) {
try {
if (className.startsWith("java.time.")) {
this.derializers.put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.ZoneId"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.Period"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance);
this.derializers.put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance);
derializer = (ObjectDeserializer)this.derializers.get(clazz);
} else if (className.startsWith("java.util.Optional")) {
this.derializers.put(Class.forName("java.util.Optional"), OptionalCodec.instance);
this.derializers.put(Class.forName("java.util.OptionalDouble"), OptionalCodec.instance);
this.derializers.put(Class.forName("java.util.OptionalInt"), OptionalCodec.instance);
this.derializers.put(Class.forName("java.util.OptionalLong"), OptionalCodec.instance);
derializer = (ObjectDeserializer)this.derializers.get(clazz);
}
} catch (Throwable var10) {
jdk8Error = true;
}
}

if (className.equals("java.nio.file.Path")) {
this.derializers.put(clazz, MiscCodec.instance);
}

if (clazz == Entry.class) {
this.derializers.put(clazz, MiscCodec.instance);
}

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

try {
Iterator var17 = ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader).iterator();

while(var17.hasNext()) {
AutowiredObjectDeserializer autowired = (AutowiredObjectDeserializer)var17.next();
Iterator var8 = autowired.getAutowiredFor().iterator();

while(var8.hasNext()) {
Type forType = (Type)var8.next();
this.derializers.put(forType, autowired);
}
}
} catch (Exception var12) {
}

if (derializer == null) {
derializer = (ObjectDeserializer)this.derializers.get(type);
}

if (derializer != null) {
return (ObjectDeserializer)derializer;
} else {
if (clazz.isEnum()) {
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) {
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 {
derializer = this.createJavaBeanDeserializer(clazz, (Type)type);
}
} else {
derializer = CollectionCodec.instance;
}

this.putDeserializer((Type)type, (ObjectDeserializer)derializer);
return (ObjectDeserializer)derializer;
}
}
}
}
}
  • 首先通过JSONType annotation = (JSONType)clazz.getAnnotation(JSONType.class);判断并获取类中注解

  • 替换className中的$.

    2.2.3.1 类加载黑名单
  • 判断是否为denyList,此时列表中只有两个线程类名

  • 判断是否以java.awt.开头,java.awt.Point、java.awt.Font、java.awt.Rectangle、java.awt.Color

15
  • 放入指定的java.time.* 和java.util.Optional*
16
  • 判断是否为java.nio.file.Path
  • 判断是否为java.util.Entry
  • 针对clazz做了一些类型的判断后,derializer = this.createJavaBeanDeserializer(clazz, (Type)type);
17
  • createJavaBeanDeserializer
    • 获取superClass,如果没有superClass=clazz,判断类的方法修饰符是否为Public
    • 判断clazz.getTypeParameters().length是否为0,如果底层泛型声明没有声明类型变量,则为0
    • ASMUtils.checkName(clazz.getSimpleName())检查类名
    • 判断clazz是否是接口
    • com.alibaba.fastjson.util.JavaBeanInfo.build创建beanInfo,其中初始化创建对象时,获取了clazzFieldsMethodsConstructor
      • 判断默认的构造方法是否为空,类不是接口,修饰符不是抽象的
      • 判断builderClass是否为空
      • 遍历所有的Method

1
2
3
TypeVariable[] tValue = List.class.getTypeParameters();
System.out.println(tValue[0].getName());
//输出为E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
boolean asmEnable = this.asmEnable;
if (asmEnable) {
JSONType jsonType = (JSONType)clazz.getAnnotation(JSONType.class);
Class superClass;
if (jsonType != null) {
superClass = jsonType.deserializer();
if (superClass != Void.class) {
try {
Object deseralizer = superClass.newInstance();
if (deseralizer instanceof ObjectDeserializer) {
return (ObjectDeserializer)deseralizer;
}
} catch (Throwable var16) {
}
}

asmEnable = jsonType.asm();
}

if (asmEnable) {
superClass = JavaBeanInfo.getBuilderClass(jsonType);
if (superClass == null) {
superClass = clazz;
}

do {
if (!Modifier.isPublic(superClass.getModifiers())) {
asmEnable = false;
break;
}

superClass = superClass.getSuperclass();
} while(superClass != Object.class && superClass != null);
}
}

if (clazz.getTypeParameters().length != 0) {
asmEnable = false;
}

if (asmEnable && this.asmFactory != null && this.asmFactory.classLoader.isExternalClass(clazz)) {
asmEnable = false;
}

if (asmEnable) {
asmEnable = ASMUtils.checkName(clazz.getSimpleName());
}

JavaBeanInfo beanInfo;
if (asmEnable) {
if (clazz.isInterface()) {
asmEnable = false;
}

beanInfo = JavaBeanInfo.build(clazz, type, this.propertyNamingStrategy);
if (asmEnable && beanInfo.fields.length > 200) {
asmEnable = false;
}

Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
if (asmEnable && defaultConstructor == null && !clazz.isInterface()) {
asmEnable = false;
}

FieldInfo[] var18 = beanInfo.fields;
int var7 = var18.length;

for(int var8 = 0; var8 < var7; ++var8) {
FieldInfo fieldInfo = var18[var8];
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)) {
asmEnable = false;
break;
}

if (fieldClass.isEnum()) {
ObjectDeserializer fieldDeser = this.getDeserializer((Type)fieldClass);
if (!(fieldDeser instanceof EnumDeserializer)) {
asmEnable = false;
break;
}
}
}
}

if (asmEnable && clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
asmEnable = false;
}

if (!asmEnable) {
return new JavaBeanDeserializer(this, clazz, type);
} else {
beanInfo = JavaBeanInfo.build(clazz, type, this.propertyNamingStrategy);

try {
return this.asmFactory.createJavaBeanDeserializer(this, beanInfo);
} catch (NoSuchMethodException var13) {
return new JavaBeanDeserializer(this, clazz, type);
} catch (JSONException var14) {
return new JavaBeanDeserializer(this, beanInfo);
} catch (Exception var15) {
throw new JSONException("create asm deserializer error, " + clazz.getName(), var15);
}
}
}
  - `Method`的一系列判断,是否大于4,是否不是静态方法,返回类型是否为void或是否为当前类的类型
  - 获取`Method`的参数的类型,如果参数类型的数组等于1,
     - 获取参数的类的注解及父类的注解`method.getAnnotation(JSONField.class)`,如果不为空,且判断annotation.deserialize()

是否为false,则继续循环

  - 判断方法名是否为`set`开头,且第三个字符是否为大写及是否小于`512`,如果不是大写,判断是否为`_`,如果不是`_`,继续判断是否是`f`,如果都不是,继续判断`MethodName`是否小于`5`,第四个字符是否是大写
  - `propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);`
  - 通过`propertyName`获取对应的`Field`
  - 如果`field`为空且字段类型是`Boolean`
  - 同样判断一下`field`是否有`Annotation`
  - 向添加`fieldList`中添加`FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures, parserFeatures, annotation, fieldAnnotation, (String)null);`,实例化`FieldInfo`的过程中,会完成一些操作,比如`Field`修改可访问属性,因此私有的`Field`也可以使用
  - 又获取了Methods,是这样的判断条件,
     - 大于4
     - 不是静态方法
     - 以`get`开头
     - 第三个字符大写
     - 不带参数
     - 返回类型是不是`Collection.class`、`Map.class`、`AtomicBoolean.class`、`AtomicInteger.class`、`AtomicLong.class`
  - 返回实例化的`JavaBeanInfo`
  • 判断字段数量不能大于200

  • 遍历字段,判断字段类型对应的类是否为Public,这里是不需要为Public,比如private String name;

    • 是否不是Public修饰符
    • 是否为Member
    • 是否是枚举类型
      1
      methodName.length() >= 4 && !Modifier.isStatic(method.getModifiers()) && methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3)) && method.getParameterTypes().length == 0 && (Collection.class.isAssignableFrom(method.getReturnType()) || Map.class.isAssignableFrom(method.getReturnType()) || AtomicBoolean.class == method.getReturnType() || AtomicInteger.class == method.getReturnType() || AtomicLong.class == method.getReturnType())
      18
  • 此时返回this.asmFactory.createJavaBeanDeserializer(this, beanInfo);

  • 判断Clazz是否为基本类型,比如int,如果是抛出异常

  • 创建一个类,类名格式:FastjsonASMDeserializer_1_User,全称:com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_1_User

  • 创建ClassWriter(),可以看出通过defineClassPublic创建这个类;最终通过ASM创建了一个JavaBeanDeserializer类型的类,将config和beanInfo传入构造方法

  • typederializer映射关系放入derializers中,估计是留着备用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo) throws Exception {
Class<?> clazz = beanInfo.clazz;
if (clazz.isPrimitive()) {
throw new IllegalArgumentException("not support type :" + clazz.getName());
} else {
String className = "FastjsonASMDeserializer_" + this.seed.incrementAndGet() + "_" + clazz.getSimpleName();
String packageName = ASMDeserializerFactory.class.getPackage().getName();
String classNameType = packageName.replace('.', '/') + "/" + className;
String classNameFull = packageName + "." + className;
ClassWriter cw = new ClassWriter();
cw.visit(49, 33, classNameType, ASMUtils.type(JavaBeanDeserializer.class), (String[])null);
this._init(cw, new ASMDeserializerFactory.Context(classNameType, config, beanInfo, 3));
this._createInstance(cw, new ASMDeserializerFactory.Context(classNameType, config, beanInfo, 3));
this._deserialze(cw, new ASMDeserializerFactory.Context(classNameType, config, beanInfo, 5));
this._deserialzeArrayMapping(cw, new ASMDeserializerFactory.Context(classNameType, config, beanInfo, 4));
byte[] code = cw.toByteArray();
Class<?> exampleClass = this.defineClassPublic(classNameFull, code, 0, code.length);
Constructor<?> constructor = exampleClass.getConstructor(ParserConfig.class, JavaBeanInfo.class);
Object instance = constructor.newInstance(config, beanInfo);
return (ObjectDeserializer)instance;
}
}

2.2.4 com.alibaba.fastjson.parser.deserializer#

获取deserializer后,调用deserializer.deserialze((DefaultJSONParser)this, clazz, fieldName);
此时再跟踪已经跟踪不了了,因为执行deserialze方法的是 创建的FastjsonASMDeserializer_1_User对象,这个对象我们跟踪不到;
这个对象对应的类是 com.alibaba.fastjson.parser.deserializer#deserialze

  1. 只能暂时静态分析,在循环获取字符串中key的过程中,如果仍然遇到@type,继续获取deserizer.deserialze方法进行解析
19
20

2.2.5 参数赋值

这里根据JavaBeanDeserializer的构造方法得知,fieldDeser对应的是DefaultFieldDeserializer类型

  • 赋值的流程是 DefaultFieldDeserializer#parseField()方法 -> FieldDeserializer#setValue
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    public void setValue(Object object, Object value) {
    if (value == null //
    && fieldInfo.fieldClass.isPrimitive()) {
    return;
    }

    try {
    Method method = fieldInfo.method;
    if (method != null) {
    if (fieldInfo.getOnly) {
    if (fieldInfo.fieldClass == AtomicInteger.class) {
    AtomicInteger atomic = (AtomicInteger) method.invoke(object);
    if (atomic != null) {
    atomic.set(((AtomicInteger) value).get());
    }
    } else if (fieldInfo.fieldClass == AtomicLong.class) {
    AtomicLong atomic = (AtomicLong) method.invoke(object);
    if (atomic != null) {
    atomic.set(((AtomicLong) value).get());
    }
    } else if (fieldInfo.fieldClass == AtomicBoolean.class) {
    AtomicBoolean atomic = (AtomicBoolean) method.invoke(object);
    if (atomic != null) {
    atomic.set(((AtomicBoolean) value).get());
    }
    } else if (Map.class.isAssignableFrom(method.getReturnType())) {
    Map map = (Map) method.invoke(object);
    if (map != null) {
    map.putAll((Map) value);
    }
    } else {
    Collection collection = (Collection) method.invoke(object);
    if (collection != null) {
    collection.addAll((Collection) value);
    }
    }
    } else {
    method.invoke(object, value);
    }
    return;
    } else {
    final Field field = fieldInfo.field;

    if (fieldInfo.getOnly) {
    if (fieldInfo.fieldClass == AtomicInteger.class) {
    AtomicInteger atomic = (AtomicInteger) field.get(object);
    if (atomic != null) {
    atomic.set(((AtomicInteger) value).get());
    }
    } else if (fieldInfo.fieldClass == AtomicLong.class) {
    AtomicLong atomic = (AtomicLong) field.get(object);
    if (atomic != null) {
    atomic.set(((AtomicLong) value).get());
    }
    } else if (fieldInfo.fieldClass == AtomicBoolean.class) {
    AtomicBoolean atomic = (AtomicBoolean) field.get(object);
    if (atomic != null) {
    atomic.set(((AtomicBoolean) value).get());
    }
    } else if (Map.class.isAssignableFrom(fieldInfo.fieldClass)) {
    Map map = (Map) field.get(object);
    if (map != null) {
    map.putAll((Map) value);
    }
    } else {
    Collection collection = (Collection) field.get(object);
    if (collection != null) {
    collection.addAll((Collection) value);
    }
    }
    } else {
    if (field != null) {
    field.set(object, value);
    }
    }
    }
    } catch (Exception e) {
    throw new JSONException("set property error, " + fieldInfo.name, e);
    }
    }

实际是通过遍历fieldInfo进行赋值,如果有setXXX方法,则通过反射调用,如果没有则通过反射对响应的Field进行赋值

21

最终返回了一个实例化的Object对象