1 Fastjson2簡介
Fastjson2
是Fastjson
的升級版,特徵:
- 協議支援:支援
JSON
/JSONB
兩種協議 - 部分解析:可以使用
JSONPath
進行部分解析獲取需要的值 - 語言支援:
Java
/Kotlin
- 場景支援:
Android8+
/服務端 - 其他特性支援:
Graal Native-Image
、JSON Schema
2 基礎使用
2.1 測試環境
環境:
JDK
版本:1.8.0_341
Fastjson2
版本:2.0.19
測試類:
@Builder
@Data
@ToString
public class Entity {
private String field1;
private Integer field2;
}
2.2 JSON
序列化
System.out.println(JSON.toJSONString(entity));
2.3 JSON
反序列化
System.out.println(JSON.parseObject(str,Entity.class));
2.4 JSONB
序列化
byte[] bytes = JSONB.toBytes(entity);
2.5 JSONB
反序列化
System.out.println(JSONB.parseObject(bytes,Entity.class));
2.6 JSON Schema
JSON Schema
可用於反序列化時對JSON
欄位進行驗證使用,配置Schema
可以透過@JSONField
/@JSONType
,這裡以@JSONField
為例:
public class Entity {
private String field1;
@JSONField(schema = "{'minimum':0,'maximum':100}")
private Integer field2;
}
測試程式碼:
Entity entity1 = Entity.builder().field2(-1).build();
Entity entity2 = Entity.builder().field2(50).build();
Entity entity3 = Entity.builder().field2(101).build();
String str1 = JSON.toJSONString(entity1);
String str2 = JSON.toJSONString(entity2);
String str3 = JSON.toJSONString(entity3);
try {
JSON.parseObject(str1, Entity.class);
} catch (Exception e) {
e.printStackTrace();
}
JSON.parseObject(str2, Entity.class);
try {
JSON.parseObject(str3, Entity.class);
} catch (Exception e) {
e.printStackTrace();
}
輸出:
2.7 JSONPath
JSONPath
可用於部分解析JSON
字串,示例:
Entity entity = Entity.builder().field1("a").field2(2).build();
// $符號表示根物件
// $.field1表示根物件的field1屬性
System.out.println(JSONPath.eval(entity,"$.field1"));
System.out.println(JSONPath.eval(entity,"$.field2"));
List<Entity> list = new ArrayList<>();
list.add(Entity.builder().field1("entity1").field2(1).build());
list.add(Entity.builder().field1("entity2").field2(2).build());
// 如果傳的是List,支援透過下標解析
// 此處是返回[0,0]下標範圍內的值
List<Entity> names = (List<Entity>)JSONPath.eval(list,"[0,0]");
System.out.println(names.get(0));
詳細的解析語法以及更多例子請參考官方文件。
2.8 AutoType
AutoType
是在序列化的時候帶上型別的一種機制,這樣在反序列化時就不需要傳入型別,實現型別自動識別,例子:
Entity entity = Entity.builder().field1("a").field2(2).build();
String str = JSON.toJSONString(entity, JSONWriter.Feature.WriteClassName);
System.out.println(str);
System.out.println(JSON.parseObject(str, Object.class, JSONReader.Feature.SupportAutoType));
輸出:
由於在Fastjson1
中出現過AutoType
漏洞,因此官方提供了一個JVM
引數完全禁止(safeMode
功能):
-Dfastjson2.parser.safeMode=true
3 底層實現探究
3.1 序列化
3.1.1 概覽
序列化的實現可以參考官方的一張類圖:
大概流程如下:
- 獲取
ObjectWriter
- 如果從
ObjectWriterProvider
快取有ObjectWriter
,直接提取 - 如果
ObjectWriterProvider
快取沒有ObjectWriter
,構造對應的ObjectWriter
,並快取 - 獲取到
ObjectWriter
後,將JavaBean
物件寫入JSONWriter
JSONWriter
對基礎型別進行寫入- 返回結果
3.1.2 入口
這裡的序列化探究以JSON.toJSONString(Object object)
作為入口:
static String toJSONString(Object object) {
// 初始化ObjectWriterProvider
JSONWriter.Context writeContext = new JSONWriter.Context(JSONFactory.defaultObjectWriterProvider);
// 格式化控制
boolean pretty = (writeContext.features & com.alibaba.fastjson2.JSONWriter.Feature.PrettyFormat.mask) != 0L;
Object jsonWriter;
// 預設有三個JSONWriter,JDK8一個,針對JDK9之後的byte[]實現的字串最佳化也有一個,還有一個基於char[]實現的UTF16
if (JDKUtils.JVM_VERSION == 8) {
jsonWriter = new JSONWriterUTF16JDK8(writeContext);
} else if ((writeContext.features & com.alibaba.fastjson2.JSONWriter.Feature.OptimizedForAscii.mask) != 0L) {
jsonWriter = new JSONWriterUTF8JDK9(writeContext);
} else {
jsonWriter = new JSONWriterUTF16(writeContext);
}
try {
// 格式化控制
JSONWriter writer = pretty ? new JSONWriterPretty((JSONWriter)jsonWriter) : jsonWriter;
String var12;
try {
if (object == null) {
// null的話直接寫入"null"字串
((JSONWriter)writer).writeNull();
} else {
// 設定根物件
((JSONWriter)writer).setRootObject(object);
Class<?> valueClass = object.getClass();
if (valueClass == JSONObject.class) {
// 如果目標類是JSNOObject,直接呼叫writer的write方法
((JSONWriter)writer).write((JSONObject)object);
} else {
// 如果不是
JSONWriter.Context context = ((JSONWriter)writer).context;
boolean fieldBased = (context.features & com.alibaba.fastjson2.JSONWriter.Feature.FieldBased.mask) != 0L;
// 透過Provider獲取ObjectWriter
ObjectWriter<?> objectWriter = context.provider.getObjectWriter(valueClass, valueClass, fieldBased);
// ObjectWriter將資料寫入JSONWriter
objectWriter.write((JSONWriter)writer, object, (Object)null, (Type)null, 0L);
}
}
// 結果
var12 = writer.toString();
// 下面的程式碼與序列化關係不大,可以不看
} catch (Throwable var10) {
if (writer != null) {
try {
((JSONWriter)writer).close();
} catch (Throwable var9) {
var10.addSuppressed(var9);
}
}
throw var10;
}
if (writer != null) {
((JSONWriter)writer).close();
}
return var12;
} catch (NumberFormatException | NullPointerException var11) {
throw new JSONException("JSON#toJSONString cannot serialize '" + object + "'", var11);
}
}
3.1.3 獲取ObjectWriterProvider
JSON.toJSONString()
入口:
JSONWriter.Context writeContext = new JSONWriter.Context(JSONFactory.defaultObjectWriterProvider);
其中會呼叫預設的構造方法初始化ObjectWriterProvider
:
public ObjectWriterProvider() {
this.init();
ObjectWriterCreator creator = null;
switch (JSONFactory.CREATOR) {
case "reflect":
creator = ObjectWriterCreator.INSTANCE;
break;
case "lambda":
creator = ObjectWriterCreatorLambda.INSTANCE;
break;
case "asm":
default:
try {
creator = ObjectWriterCreatorASM.INSTANCE;
} catch (Throwable var5) {
}
if (creator == null) {
creator = ObjectWriterCreatorLambda.INSTANCE;
}
}
this.creator = (ObjectWriterCreator)creator;
}
ObjectWriterCreator
採取的是單例模式,預設採用ASM
動態位元組碼實現。
3.1.4 獲取ObjectWriter
有了ObjectWriterProvider
後,下一步就是獲取ObjectWriter
,也就是JSON.toJSONString()
中的:
JSONWriter.Context context = ((JSONWriter)writer).context;
boolean fieldBased = (context.features & com.alibaba.fastjson2.JSONWriter.Feature.FieldBased.mask) != 0L;
ObjectWriter<?> objectWriter = context.provider.getObjectWriter(valueClass, valueClass, fieldBased);
getObjectWriter()
如下:
public ObjectWriter getObjectWriter(Type objectType, Class objectClass, boolean fieldBased) {
// fieldBased是基於欄位序列化的意思
// false的話表示基於getter序列化
// 根據不同的型別從不同的快取map中獲取
ObjectWriter objectWriter = fieldBased ? (ObjectWriter)this.cacheFieldBased.get(objectType) : (ObjectWriter)this.cache.get(objectType);
// 首次獲取應該為null
if (objectWriter != null) {
return (ObjectWriter)objectWriter;
} else {
// 這個useModules布林變數筆者不太瞭解
// 這裡的邏輯是 基於欄位反序列化 並且 目標class不為空 並且 目標class可以賦值給Iterable 並且 目標class不能賦值給class
boolean useModules = true;
if (fieldBased && objectClass != null && Iterable.class.isAssignableFrom(objectClass) && !Collection.class.isAssignableFrom(objectClass)) {
useModules = false;
}
// 這裡的例子是true
if (useModules) {
for(int i = 0; i < this.modules.size(); ++i) {
// 獲取ObjectWriterModule
ObjectWriterModule module = (ObjectWriterModule)this.modules.get(i);
objectWriter = module.getObjectWriter(objectType, objectClass);
// 為null
if (objectWriter != null) {
ObjectWriter previous = fieldBased ? (ObjectWriter)this.cacheFieldBased.putIfAbsent(objectType, objectWriter) : (ObjectWriter)this.cache.putIfAbsent(objectType, objectWriter);
if (previous != null) {
objectWriter = previous;
}
return (ObjectWriter)objectWriter;
}
}
}
// 第一次執行暫時還拿不到ObjectWriter,這裡的條件全部符合
if (objectWriter == null && objectClass != null && !fieldBased) {
switch (objectClass.getName()) {
// 針對Guava庫的map內建了ObjectWriter
case "com.google.common.collect.HashMultimap":
case "com.google.common.collect.LinkedListMultimap":
case "com.google.common.collect.LinkedHashMultimap":
case "com.google.common.collect.ArrayListMultimap":
case "com.google.common.collect.TreeMultimap":
objectWriter = GuavaSupport.createAsMapWriter(objectClass);
break;
// 不是JSONObject類
case "com.alibaba.fastjson.JSONObject":
objectWriter = ObjectWriterImplMap.of(objectClass);
}
}
// ObjectWriter還沒拿到
if (objectWriter == null) {
// 第一次拿需要透過ObjectWriterCreator()去建立
ObjectWriterCreator creator = this.getCreator();
if (objectClass == null) {
objectClass = TypeUtils.getMapping(objectType);
}
// 建立ObjectWriter
// ObjectWriter的裡面會建立FieldWriter,這裡面的邏輯很長,經過一些列複雜邏輯的判斷,再針對欄位獲取
objectWriter = creator.createObjectWriter(objectClass, fieldBased ? Feature.FieldBased.mask : 0L, this);
// 放入快取
ObjectWriter previous = fieldBased ? (ObjectWriter)this.cacheFieldBased.putIfAbsent(objectType, objectWriter) : (ObjectWriter)this.cache.putIfAbsent(objectType, objectWriter);
if (previous != null) {
objectWriter = previous;
}
}
return (ObjectWriter)objectWriter;
}
}
其中FiledWriter
獲取邏輯如下:
// ObjectWriterCreatorASM.java 236行左右的位置
BeanUtils.fields(objectClass, (field) -> {
if (fieldBased || Modifier.isPublic(field.getModifiers())) {
fieldInfo.init();
// 建立FieldWriter
FieldWriter fieldWriter = this.creteFieldWriter(objectClass, writerFeatures, provider.modules, beanInfo, fieldInfo, field);
if (fieldWriter != null) {
// 放入快取
fieldWriterMap.putIfAbsent(fieldWriter.fieldName, fieldWriter);
}
}
});
3.1.5 write()
操作
獲取到ObjectWriter
之後,就可以進行write()
操作了,JSON.toJSONString()
入口:
objectWriter.write((JSONWriter)writer, object, (Object)null, (Type)null, 0L);
由於自定義類的ObjectWriter
是執行時拿到的,無法透過除錯獲取到,但是可以透過內建的ObjectWriter
來判斷大概的write()
流程:
比如LocalDateWriter
的write()
如下:
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
try {
int year = (Integer)this.getYear.invoke(object);
int monthOfYear = (Integer)this.getMonthOfYear.invoke(object);
int dayOfMonth = (Integer)this.getDayOfMonth.invoke(object);
Object chronology = this.getChronology.invoke(object);
if (chronology != this.utc && chronology != null) {
jsonWriter.startObject();
// 寫入key
jsonWriter.writeName("year");
// 寫入value
jsonWriter.writeInt32(year);
jsonWriter.writeName("month");
jsonWriter.writeInt32(monthOfYear);
jsonWriter.writeName("day");
jsonWriter.writeInt32(dayOfMonth);
jsonWriter.writeName("chronology");
jsonWriter.writeAny(chronology);
jsonWriter.endObject();
} else {
LocalDate localDate = LocalDate.of(year, monthOfYear, dayOfMonth);
DateTimeFormatter formatter = this.getDateFormatter();
if (formatter == null) {
formatter = jsonWriter.getContext().getDateFormatter();
}
if (formatter == null) {
jsonWriter.writeLocalDate(localDate);
} else {
String str = formatter.format(localDate);
jsonWriter.writeString(str);
}
}
} catch (InvocationTargetException | IllegalAccessException var14) {
throw new JSONException("write LocalDateWriter error", var14);
}
}
根據getter
獲取欄位值並呼叫對應的Writer
去寫JSON
。
3.2 反序列化
3.2.1 概覽
反序列化也可以參考官方的一張圖:
大概流程與序列化類似:
- 獲取
ObjectReader
- 如果
ObjectReaderProvider
有快取,從快取提取 - 如果
ObjectReaderProvider
沒有快取,建立ObjectReader
並且快取到ObjectReaderProvider
中 - 透過
JSONReader
得到Object
- 返回結果
3.2.2 入口
Entity entity = Entity.builder().field1("a").field2(2).build();
String str = JSON.toJSONString(entity);
System.out.println(JSON.parseObject(str,Entity.class));
其中parseObject()
如下:
static <T> T parseObject(String text, Class<T> clazz) {
if (text != null && !text.isEmpty()) {
// 獲取JSONReader
JSONReader reader = JSONReader.of(text);
Object var7;
try {
JSONReader.Context context = reader.context;
// 判斷是否基於欄位反序列化
boolean fieldBased = (context.features & Feature.FieldBased.mask) != 0L;
// 透過ObjectReaderProvider獲取ObjectReader
// 這個context看起來和ObjectReaderProvider無關,實際上內部實現Context包含了ObjectReaderProvider
ObjectReader<T> objectReader = context.provider.getObjectReader(clazz, fieldBased);
// 反序列化核心方法
T object = objectReader.readObject(reader, (Type)null, (Object)null, 0L);
if (reader.resolveTasks != null) {
reader.handleResolveTasks(object);
}
if (reader.ch != 26 && (reader.context.features & Feature.IgnoreCheckClose.mask) == 0L) {
throw new JSONException(reader.info("input not end"));
}
var7 = object;
} catch (Throwable var9) {
if (reader != null) {
try {
reader.close();
} catch (Throwable var8) {
var9.addSuppressed(var8);
}
}
throw var9;
}
if (reader != null) {
reader.close();
}
return var7;
} else {
return null;
}
}
3.2.3 獲取JSONReader
JSON.parseObject()
入口:
JSONReader reader = JSONReader.of(text);
其中JSONReader.of()
實現如下:
public static JSONReader of(String str) {
if (str == null) {
throw new NullPointerException();
} else {
// 建立Context
// Context內部包含了ObjectReaderProvider
Context context = JSONFactory.createReadContext();
int length;
// 測試環境JDK8,此處if不成立
if (JDKUtils.JVM_VERSION > 8 && JDKUtils.UNSAFE_SUPPORT) {
try {
length = JDKUtils.STRING_CODER != null ? JDKUtils.STRING_CODER.applyAsInt(str) : UnsafeUtils.getStringCoder(str);
if (length == 0) {
byte[] bytes = JDKUtils.STRING_VALUE != null ? (byte[])JDKUtils.STRING_VALUE.apply(str) : UnsafeUtils.getStringValue(str);
return new JSONReaderASCII(context, str, bytes, 0, bytes.length);
}
} catch (Exception var4) {
throw new JSONException("unsafe get String.coder error");
}
}
length = str.length();
char[] chars;
// 測試環境JDK8
if (JDKUtils.JVM_VERSION == 8) {
// 獲取char array
chars = JDKUtils.getCharArray(str);
} else {
chars = str.toCharArray();
}
// 由於JDK8的String還是使用char[]實現的,所以返回UTF16的JSONReader
return new JSONReaderUTF16(context, str, chars, 0, length);
}
}
3.2.4 獲取ObjectReader
JSON.parseObject()
入口:
ObjectReader<T> objectReader = context.provider.getObjectReader(clazz, fieldBased);
getObjectReader()
如下:
public ObjectReader getObjectReader(Type objectType, boolean fieldBased) {
if (objectType == null) {
objectType = Object.class;
}
// 有快取直接從快取提取
ObjectReader objectReader = fieldBased ? (ObjectReader)this.cacheFieldBased.get(objectType) : (ObjectReader)this.cache.get(objectType);
// 第一次獲取ObjectReader為null
if (objectReader != null) {
return objectReader;
} else {
Iterator var4 = this.modules.iterator();
ObjectReader previous;
while(var4.hasNext()) {
ObjectReaderModule module = (ObjectReaderModule)var4.next();
// 獲取到的ObjectReader為null
objectReader = module.getObjectReader(this, (Type)objectType);
if (objectReader != null) {
previous = fieldBased ? (ObjectReader)this.cacheFieldBased.putIfAbsent(objectType, objectReader) : (ObjectReader)this.cache.putIfAbsent(objectType, objectReader);
if (previous != null) {
objectReader = previous;
}
return objectReader;
}
}
Type rawType;
// 條件不符合
if (objectType instanceof TypeVariable) {
Type[] bounds = ((TypeVariable)objectType).getBounds();
if (bounds.length > 0) {
rawType = bounds[0];
if (rawType instanceof Class) {
previous = this.getObjectReader(rawType, fieldBased);
if (previous != null) {
ObjectReader previous = this.getPreviousObjectReader(fieldBased, (Type)objectType, previous);
if (previous != null) {
previous = previous;
}
return previous;
}
}
}
}
// 條件不符合
if (objectType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)objectType;
rawType = parameterizedType.getRawType();
Type[] typeArguments = parameterizedType.getActualTypeArguments();
if (rawType instanceof Class) {
Class rawClass = (Class)rawType;
boolean generic = false;
for(Class clazz = rawClass; clazz != Object.class; clazz = clazz.getSuperclass()) {
if (clazz.getTypeParameters().length > 0) {
generic = true;
break;
}
}
if (typeArguments.length == 0 || !generic) {
ObjectReader rawClassReader = this.getObjectReader(rawClass, fieldBased);
if (rawClassReader != null) {
ObjectReader previous = this.getPreviousObjectReader(fieldBased, (Type)objectType, rawClassReader);
if (previous != null) {
rawClassReader = previous;
}
return rawClassReader;
}
}
}
}
Class<?> objectClass = TypeUtils.getMapping((Type)objectType);
String className = objectClass.getName();
if (objectReader == null && !fieldBased) {
switch (className) {
// 針對Guava的MultiMap,這裡的條件不符合
case "com.google.common.collect.ArrayListMultimap":
objectReader = ObjectReaderImplMap.of((Type)null, objectClass, 0L);
}
}
// ObjectReader為null
if (objectReader == null) {
// 獲取ObjectReaderCreator
ObjectReaderCreator creator = this.getCreator();
// 建立ObjectReader
objectReader = creator.createObjectReader(objectClass, (Type)objectType, fieldBased, this);
}
previous = this.getPreviousObjectReader(fieldBased, (Type)objectType, objectReader);
if (previous != null) {
objectReader = previous;
}
return objectReader;
}
}
在建立ObjectReader
的同時,會在其中建立FieldReader
:
// ObjectReaderCreator.java 453
FieldReader[] fieldReaderArray = this.createFieldReaders(objectClass, objectType, beanInfo, fieldBased, provider);
3.2.5 read()
操作
有了ObjectReader
之後就可以進行具體的read()
操作了,JSON.parseObject()
入口:
T object = objectReader.readObject(reader, (Type)null, (Object)null, 0L);
此處的readObject()
如下:
// ObjectReaderNoneDefaultConstructor.java 171行
public T readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
// 判斷是否帶有JSONReader.Feature.ErrorOnNoneSerializable
if (!this.serializable) {
jsonReader.errorOnNoneSerializable(this.objectClass);
}
// 是否JSONB,不符合
if (jsonReader.isJSONB()) {
return this.readJSONBObject(jsonReader, fieldType, fieldName, 0L);
} else if (jsonReader.isArray() && jsonReader.isSupportBeanArray(features | this.features)) {
// 是陣列而且支援JSONReader.Feature.SupportArrayToBean,不符合
jsonReader.next();
LinkedHashMap<Long, Object> valueMap = null;
for(int i = 0; i < this.fieldReaders.length; ++i) {
Object fieldValue = this.fieldReaders[i].readFieldValue(jsonReader);
if (valueMap == null) {
valueMap = new LinkedHashMap();
}
long hash = this.fieldReaders[i].fieldNameHash;
valueMap.put(hash, fieldValue);
}
if (!jsonReader.nextIfMatch(']')) {
throw new JSONException(jsonReader.info("array not end, " + jsonReader.current()));
} else {
jsonReader.nextIfMatch(',');
return this.createInstanceNoneDefaultConstructor((Map)(valueMap == null ? Collections.emptyMap() : valueMap));
}
} else {
// 讀取字元
boolean objectStart = jsonReader.nextIfObjectStart();
// 條件為false,進入else
if (!objectStart && !jsonReader.isTypeRedirect() && jsonReader.nextIfEmptyString()) {
return null;
} else {
// 獲取Context,讀取其中的Features
JSONReader.Context context = jsonReader.getContext();
long featuresAll = this.features | features | context.getFeatures();
// 此處儲存物件的值
// key是欄位的long雜湊值,雜湊採取的是fnv1a 64演算法生成的
// value是欄位的具體值
LinkedHashMap<Long, Object> valueMap = null;
// 讀取
for(int i = 0; !jsonReader.nextIfMatch('}'); ++i) {
// 讀取欄位名對應的hashCode
long hashCode = jsonReader.readFieldNameHashCode();
if (hashCode != 0L) {
if (hashCode == this.typeKeyHashCode && i == 0) {
long typeHash = jsonReader.readTypeHashCode();
// 此處if條件不符合
if (typeHash != this.typeNameHash) {
boolean supportAutoType = (featuresAll & Feature.SupportAutoType.mask) != 0L;
ObjectReader autoTypeObjectReader;
String typeName;
if (supportAutoType) {
autoTypeObjectReader = context.getObjectReaderAutoType(typeHash);
if (autoTypeObjectReader == null) {
typeName = jsonReader.getString();
autoTypeObjectReader = context.getObjectReaderAutoType(typeName, this.objectClass, this.features);
}
} else {
typeName = jsonReader.getString();
autoTypeObjectReader = context.getObjectReaderAutoType(typeName, this.objectClass);
}
if (autoTypeObjectReader == null) {
typeName = jsonReader.getString();
autoTypeObjectReader = context.getObjectReaderAutoType(typeName, this.objectClass, this.features);
}
if (autoTypeObjectReader != null) {
Object object = autoTypeObjectReader.readObject(jsonReader, fieldType, fieldName, 0L);
jsonReader.nextIfMatch(',');
return object;
}
}
} else {
// 獲取欄位名雜湊對應的FieldReader
FieldReader fieldReader = this.getFieldReader(hashCode);
// 條件不符合
if (fieldReader == null && (featuresAll & Feature.SupportSmartMatch.mask) != 0L) {
long hashCodeLCase = jsonReader.getNameHashCodeLCase();
if (hashCodeLCase != hashCode) {
fieldReader = this.getFieldReaderLCase(hashCodeLCase);
}
}
// fieldReader不為null
if (fieldReader == null) {
this.processExtra(jsonReader, (Object)null);
} else {
// 讀取欄位值
Object fieldValue = fieldReader.readFieldValue(jsonReader);
if (valueMap == null) {
valueMap = new LinkedHashMap();
}
long hash;
if (fieldReader instanceof FieldReaderObjectParam) {
hash = ((FieldReaderObjectParam)fieldReader).paramNameHash;
} else {
hash = fieldReader.fieldNameHash;
}
// 寫入
valueMap.put(hash, fieldValue);
}
}
}
}
// 構造物件
T object = this.createInstanceNoneDefaultConstructor((Map)(valueMap == null ? Collections.emptyMap() : valueMap));
if (this.setterFieldReaders != null && valueMap != null) {
for(int i = 0; i < this.setterFieldReaders.length; ++i) {
FieldReader fieldReader = this.setterFieldReaders[i];
// 讀取欄位值
Object fieldValue = valueMap.get(fieldReader.fieldNameHash);
if (fieldValue != null) {
// 透過setter注入
fieldReader.accept(object, fieldValue);
}
}
}
jsonReader.nextIfMatch(',');
return object;
}
}
}
4 結尾
其實文章中很多細節的地方由於篇幅的限制無法過於詳細的解釋,比如內建的各型別的Reader
/Writer
具體是如何獲取值進行序列化/反序列操作的,想要深入探究這部分就只能自己去挖原始碼了。另外需要注意的是,文章的環境是在JDK8
下的,由於Fastjson2
在不同的JDK
下會有不同的序列化實現,因此僅供參考。
最後,關於效能的比較,可以參考官方的比較基準。