fastjson深度原始碼解析- 反序列化(二)
阿新 • • 發佈:2019-02-08
反序列化回撥介面實現分析
內部註冊的反序列化
fastjson針對常用的型別已經註冊了反序列化實現方案,根據原始碼註冊com.alibaba.fastjson.parser.ParserConfig#initDeserializers
可以得到列表:
註冊的型別 | 反序列化例項 | 是否支援序列化 | 是否支援反序列化 |
---|---|---|---|
SimpleDateFormat | MiscCodec | 是 | 是 |
Timestamp | SqlDateDeserializer | - | 是 |
Date | SqlDateDeserializer | - | 是 |
Time | TimeDeserializer | - | 是 |
Date | DateCodec | 是 | 是 |
Calendar | CalendarCodec | 是 | 是 |
XMLGregorianCalendar | CalendarCodec | 是 | 是 |
JSONObject | MapDeserializer | - | 是 |
JSONArray | CollectionCodec | 是 | 是 |
Map | MapDeserializer | - | 是 |
HashMap | MapDeserializer | - | 是 |
LinkedHashMap | MapDeserializer | - | 是 |
TreeMap | MapDeserializer | - | 是 |
ConcurrentMap | MapDeserializer | - | 是 |
ConcurrentHashMap | MapDeserializer | - | 是 |
Collection | CollectionCodec | 是 | 是 |
List | CollectionCodec | 是 | 是 |
ArrayList | CollectionCodec | 是 | 是 |
Object | JavaObjectDeserializer | - | 是 |
String | StringCodec | 是 | 是 |
StringBuffer | StringCodec | 是 | 是 |
StringBuilder | StringCodec | 是 | 是 |
char | CharacterCodec | 是 | 是 |
Character | CharacterCodec | 是 | 是 |
byte | NumberDeserializer | - | 是 |
Byte | NumberDeserializer | - | 是 |
short | NumberDeserializer | - | 是 |
Short | NumberDeserializer | - | 是 |
int | IntegerCodec | 是 | 是 |
Integer | IntegerCodec | 是 | 是 |
long | LongCodec | 是 | 是 |
Long | LongCodec | 是 | 是 |
BigInteger | BigIntegerCodec | 是 | 是 |
BigDecimal | BigDecimalCodec | 是 | 是 |
float | FloatCodec | 是 | 是 |
Float | FloatCodec | 是 | 是 |
double | NumberDeserializer | 是 | 是 |
Double | NumberDeserializer | 是 | 是 |
boolean | BooleanCodec | 是 | 是 |
Boolean | BooleanCodec | 是 | 是 |
Class | MiscCodec | 是 | 是 |
char[] | CharArrayCodec | 是 | 是 |
AtomicBoolean | BooleanCodec | 是 | 是 |
AtomicBoolean | IntegerCodec | 是 | 是 |
AtomicLong | LongCodec | 是 | 是 |
AtomicReference | ReferenceCodec | 是 | 是 |
WeakReference | ReferenceCodec | 是 | 是 |
SoftReference | ReferenceCodec | 是 | 是 |
UUID | MiscCodec | 是 | 是 |
TimeZone | MiscCodec | 是 | 是 |
Locale | MiscCodec | 是 | 是 |
Currency | MiscCodec | 是 | 是 |
InetAddress | MiscCodec | 是 | 是 |
Inet4Address | MiscCodec | 是 | 是 |
Inet6Address | MiscCodec | 是 | 是 |
InetSocketAddress | MiscCodec | 是 | 是 |
File | MiscCodec | 是 | 是 |
URI | MiscCodec | 是 | 是 |
URL | MiscCodec | 是 | 是 |
Pattern | MiscCodec | 是 | 是 |
Charset | MiscCodec | 是 | 是 |
JSONPath | MiscCodec | 是 | 是 |
Number | NumberDeserializer | - | 是 |
AtomicIntegerArray | AtomicCodec | 是 | 是 |
AtomicLongArray | AtomicCodec | 是 | 是 |
StackTraceElement | StackTraceElementDeserializer | - | 是 |
Serializable | JavaObjectDeserializer | - | 是 |
Cloneable | JavaObjectDeserializer | - | 是 |
Comparable | JavaObjectDeserializer | - | 是 |
Closeable | JavaObjectDeserializer | - | 是 |
JSONPObject | JSONPDeserializer | - | 是 |
通過上面表格發現幾乎把所有JDK常用的型別都註冊了一遍,目的是在執行時能夠查詢到特定的反序列化例項而不需要使用預設Java的反序列化例項。
我們先從常見的型別開始分析反序列化實現。
BooleanCodec反序列化
public <T> T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
final JSONLexer lexer = parser.lexer;
Boolean boolObj;
try {
/** 遇到true型別的token,預讀下一個token */
if (lexer.token() == JSONToken.TRUE) {
lexer.nextToken(JSONToken.COMMA);
boolObj = Boolean.TRUE;
/** 遇到false型別的token,預讀下一個token */
} else if (lexer.token() == JSONToken.FALSE) {
lexer.nextToken(JSONToken.COMMA);
boolObj = Boolean.FALSE;
} else if (lexer.token() == JSONToken.LITERAL_INT) {
/** 遇到整數型別的token,預讀下一個token */
int intValue = lexer.intValue();
lexer.nextToken(JSONToken.COMMA);
/** 1代表true,其他情況false */
if (intValue == 1) {
boolObj = Boolean.TRUE;
} else {
boolObj = Boolean.FALSE;
}
} else {
Object value = parser.parse();
if (value == null) {
return null;
}
/** 處理其他情況,比如Y,T代表true */
boolObj = TypeUtils.castToBoolean(value);
}
} catch (Exception ex) {
throw new JSONException("parseBoolean error, field : " + fieldName, ex);
}
/** 如果是原子型別 */
if (clazz == AtomicBoolean.class) {
return (T) new AtomicBoolean(boolObj.booleanValue());
}
return (T) boolObj;
}
每次反序列化拿到token是,當前記錄的字元ch
變數實際是token結尾的下一個字元,boolean
型別欄位會觸發該介面。
CharacterCodec反序列化
public <T> T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
/** 根據token解析型別 */
Object value = parser.parse();
return value == null
? null
/** 轉換成char型別,如果是string取字串第一個char */
: (T) TypeUtils.castToChar(value);
}
public Object parse() {
return parse(null);
}
看著反序列化應該挺簡單,但是內部解析值委託給了DefaultJSONParser#parse(java.lang.Object)
, 會把字串解析取第一個字元處理:
public Object parse(Object fieldName) {
final JSONLexer lexer = this.lexer;
switch (lexer.token()) {
/**
* ...忽略其他型別token,後面遇到會講解
* /
case LITERAL_STRING:
/** 探測到是字串型別,解析值 */
String stringLiteral = lexer.stringVal();
lexer.nextToken(JSONToken.COMMA);
if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
JSONScanner iso8601Lexer = new JSONScanner(stringLiteral);
try {
if (iso8601Lexer.scanISO8601DateIfMatch()) {
return iso8601Lexer.getCalendar().getTime();
}
} finally {
iso8601Lexer.close();
}
}
return stringLiteral;
/**
* ...忽略其他型別token,後面遇到會講解
* /
}
}
IntegerCodec反序列化
public <T> T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
final JSONLexer lexer = parser.lexer;
final int token = lexer.token();
/** 如果解析到null值,返回null */
if (token == JSONToken.NULL) {
lexer.nextToken(JSONToken.COMMA);
return null;
}
Integer intObj;
try {
if (token == JSONToken.LITERAL_INT) {
/** 整型字面量,預讀下一個token */
int val = lexer.intValue();
lexer.nextToken(JSONToken.COMMA);
intObj = Integer.valueOf(val);
} else if (token == JSONToken.LITERAL_FLOAT) {
/** 浮點數字面量,預讀下一個token */
BigDecimal decimalValue = lexer.decimalValue();
lexer.nextToken(JSONToken.COMMA);
intObj = Integer.valueOf(decimalValue.intValue());
} else {
if (token == JSONToken.LBRACE) {
/** 處理歷史原因反序列化AtomicInteger成map */
JSONObject jsonObject = new JSONObject(true);
parser.parseObject(jsonObject);
intObj = TypeUtils.castToInt(jsonObject);
} else {
/** 處理其他情況 */
Object value = parser.parse();
intObj = TypeUtils.castToInt(value);
}
}
} catch (Exception ex) {
throw new JSONException("parseInt error, field : " + fieldName, ex);
}
if (clazz == AtomicInteger.class) {
return (T) new AtomicInteger(intObj.intValue());
}
return (T) intObj;
}
針對特殊場景AutomicInteger型別,可以通過單元測試com.alibaba.json.bvt.parser.AtomicIntegerComptableAndroidTest#test_for_compatible_zero
進行動手實踐除錯:
public void test_for_compatible_zero() throws Exception {
String text = "{\"andIncrement\":-1,\"andDecrement\":0}";
assertEquals(0, JSON.parseObject(text, AtomicInteger.class).intValue());
}
繼續對parseObject(jsonObject)
進行分析:
public Object parseObject(final Map object) {
return parseObject(object, null);
}
LongCodec反序列化
因為和整數反序列化極其類似,請參考IntegerCodec
不進行冗餘分析。
FloatCodec反序列化
public static <T> T deserialze(DefaultJSONParser parser) {
final JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.LITERAL_INT) {
/** 整型字面量,預讀下一個token */
String val = lexer.numberString();
lexer.nextToken(JSONToken.COMMA);
return (T) Float.valueOf(Float.parseFloat(val));
}
if (lexer.token() == JSONToken.LITERAL_FLOAT) {
/** 浮點數字面量,預讀下一個token */
float val = lexer.floatValue();
lexer.nextToken(JSONToken.COMMA);
return (T) Float.valueOf(val);
}
/** 處理其他情況 */
Object value = parser.parse();
if (value == null) {
return null;
}
return (T) TypeUtils.castToFloat(value);
}
BigDecimalCodec反序列化
public static <T> T deserialze(DefaultJSONParser parser) {
final JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.LITERAL_INT) {
/** 整型字面量,預讀下一個token */
BigDecimal decimalValue = lexer.decimalValue();
lexer.nextToken(JSONToken.COMMA);
return (T) decimalValue;
}
if (lexer.token() == JSONToken.LITERAL_FLOAT) {
/** 浮點數字面量,預讀下一個token */
BigDecimal val = lexer.decimalValue();
lexer.nextToken(JSONToken.COMMA);
return (T) val;
}
Object value = parser.parse();
return value == null //
? null //
: (T) TypeUtils.castToBigDecimal(value);
}
StringCodec反序列化
public <T> T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
if (clazz == StringBuffer.class) {
/** 將解析的字元序列轉換成StringBuffer */
final JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.LITERAL_STRING) {
/** 字串字面量,預讀下一個token */
String val = lexer.stringVal();
lexer.nextToken(JSONToken.COMMA);
return (T) new StringBuffer(val);
}
Object value = parser.parse();
if (value == null) {
return null;
}
return (T) new StringBuffer(value.toString());
}
if (clazz == StringBuilder.class) {
/** 將解析的字元序列轉換成StringBuilder */
final JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.LITERAL_STRING) {
String val = lexer.stringVal();
/** 字串字面量,預讀下一個token */
lexer.nextToken(JSONToken.COMMA);
return (T) new StringBuilder(val);
}
Object value = parser.parse();
if (value == null) {
return null;
}
return (T) new StringBuilder(value.toString());
}
return (T) deserialze(parser);
}
@SuppressWarnings("unchecked")
public static <T> T deserialze(DefaultJSONParser parser) {
final JSONLexer lexer = parser.getLexer();
if (lexer.token() == JSONToken.LITERAL_STRING) {
/** 字串字面量,預讀下一個token */
String val = lexer.stringVal();
lexer.nextToken(JSONToken.COMMA);
return (T) val;
}
if (lexer.token() == JSONToken.LITERAL_INT) {
/** 整型字面量,預讀下一個token */
String val = lexer.numberString();
lexer.nextToken(JSONToken.COMMA);
return (T) val;
}
Object value = parser.parse();
if (value == null) {
return null;
}
return (T) value.toString();
}
ObjectArrayCodec反序列化
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
final JSONLexer lexer = parser.lexer;
int token = lexer.token();
if (token == JSONToken.NULL) {
/** 解析到Null,預讀下一個token */
lexer.nextToken(JSONToken.COMMA);
return null;
}
if (token == JSONToken.LITERAL_STRING || token == JSONToken.HEX) {
byte[] bytes = lexer.bytesValue();
lexer.nextToken(JSONToken.COMMA);
if (bytes.length == 0 && type != byte[].class) {
return null;
}
return (T) bytes;
}
Class componentClass;
Type componentType;
if (type instanceof GenericArrayType) {
GenericArrayType clazz = (GenericArrayType) type;
/** 獲取泛型陣列真實引數型別 */
componentType = clazz.getGenericComponentType();
if (componentType instanceof TypeVariable) {
TypeVariable typeVar = (TypeVariable) componentType;
Type objType = parser.getContext().type;
if (objType instanceof ParameterizedType) {
/** 獲取泛型引數化型別,eg: Collection<String> */
ParameterizedType objParamType = (ParameterizedType) objType;
Type objRawType = objParamType.getRawType();
Type actualType = null;
if (objRawType instanceof Class) {
/** 遍歷Class包含的引數化型別,查詢與泛型陣列型別名字一致的作為真實型別 */
TypeVariable[] objTypeParams = ((Class) objRawType).getTypeParameters();
for (int i = 0; i < objTypeParams.length; ++i) {
if (objTypeParams[i].getName().equals(typeVar.getName())) {
actualType = objParamType.getActualTypeArguments()[i];
}
}
}
if (actualType instanceof Class) {
componentClass = (Class) actualType;
} else {
componentClass = Object.class;
}
} else {
// 獲取陣列型別上界
componentClass = TypeUtils.getClass(typeVar.getBounds()[0]);
}
} else {
componentClass = TypeUtils.getClass(componentType);
}
} else {
/** 非泛型陣列,普通物件陣列 */
Class clazz = (Class) type;
componentType = componentClass = clazz.getComponentType();
}
JSONArray array = new JSONArray();
/** 根據token解析陣列元素放到array中 */
parser.parseArray(componentType, array, fieldName);
return (T) toObjectArray(parser, componentClass, array);
}
JavaBeanDeserializer反序列化
為了節省冗餘的分析,我們主要分析最複雜的預設JavaBeanDeserializer
反序列化實現。
public JavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo){
/** java物件類名稱 */
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;
}
}
建構函式就是簡單構造類欄位對應的反序列化例項而已,接下來看下關鍵實現:
protected <T> T deserialze(DefaultJSONParser parser,
Type type,
Object fieldName,
Object object,
int features,
int[] setFlags) {
if (type == JSON.class || type == JSONObject.class) {
/** 根據當前token型別判斷解析物件 */
return (T) parser.parse();
}
final JSONLexerBase lexer = (JSONLexerBase) parser.lexer;
final ParserConfig config = parser.getConfig();
int token = lexer.token();
if (token == JSONToken.NULL) {
/** 解析null,預讀下一個token並返回 */
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) {
/** 將陣列值反序列化為物件,根據sortedFieldDeserializers依次寫欄位值 */
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();
/** 讀到空值字串,返回null */
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;
}
StringBuffer buf = (new StringBuffer()) //
.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;
}
String typeKey = beanInfo.typeKey;
for (int fieldIndex = 0;; fieldIndex++) {
String key = null;
FieldDeserializer fieldDeser = null;
FieldInfo fieldInfo = null;
Class<?> fieldClass = null;
JSONField feildAnnotation = null;
/** 檢查是否所有欄位都已經處理 */
if (fieldIndex < sortedFieldDeserializers.length) {
fieldDeser = sortedFieldDeserializers[fieldIndex];
fieldInfo = fieldDeser.fieldInfo;
fieldClass = fieldInfo.fieldClass;
feildAnnotation = fieldInfo.getAnnotation();
}
boolean matchField = false;
boolean valueParsed = false;
Object fieldValue = null;
if (fieldDeser != null) {
char[] name_chars = fieldInfo.name_chars;
if (fieldClass == int.class || fieldClass == Integer.class) {
/** 掃描整數值 */
fieldValue = lexer.scanFieldInt(name_chars);
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) {
/** 掃描長整型值 */
fieldValue = lexer.scanFieldLong(name_chars);
if (lexer.matchStat > 0) {
matchField = true;
valueParsed = true;
} else if (lexer.matchStat == JSONLexer.NOT_MATCH_NAME) {
continue;
}
} else if (fieldClass == String.class) {
/** 掃描字串值 */
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值 */
fieldValue = lexer.scanFieldBoolean(name_chars);
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) {
/** 掃描浮點值 */
fieldValue = lexer.scanFieldFloat(name_chars);
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值 */
fieldValue = lexer.scanFieldDouble(name_chars);
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;
}
}
/** 如果當前字串的json不匹配當前欄位名稱 */
if (!matchField) {
/** 將當前的欄位名稱加入符號表 */
key = lexer.scanSymbol(parser.symbolTable);
/** 當前是無效的欄位識別符號,比如是,等符號 */
if (key == null) {
token = lexer.token();
if (token == JSONToken.RBRACE) {
/** 結束花括號, 預讀下一個token */
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 {
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);
/** 忽略字串中包含@type解析 */
if (typeName.equals(beanInfo.typeName)|| parser.isEnabled(Feature.IgnoreAutoType)) {
if (lexer.token() == JSONToken.RBRACE) {
lexer.nextToken();
break;
}
continue;
}
/** 根據列舉seeAlso查詢反序列化例項 */
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) {
object = createInstance(parser, type);
if (object == null) {
fieldValues = new HashMap<String, Object>(this.fieldDeserializers.length);
}
childContext = parser.setContext(context, object, fieldName);