当时我是用toJavaObject转的json字符串,我的javabean里有个list集合,导致转换之后的javabean对象里有list集合的地址索引对象!!!
toJavaObjec没有处理json转换对象$ref关键词,而parseObject方法处理了!
JSON.parseObject(String text, Class<T>)
JSONObject.toJavaObject(JSON json, Class<T> clazz)
两个方法都是JSON类的方法,区别是:
parseObject的第一个参数是json字符串;
toJavaObject的第一个参数是json对象;
parseObject该方法是最主要字段转换实现方法:
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();
}
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;
}
if (beanInfo.factoryMethod != null && beanInfo.fields.length == 1) {
try {
FieldInfo field = beanInfo.fields[0];
if (field.fieldClass == Integer.class) {
if (token == JSONToken.LITERAL_INT) {
int intValue = lexer.intValue();
lexer.nextToken();
return (T) createFactoryInstance(config, intValue);
}
} else if (field.fieldClass == String.class) {
if (token == JSONToken.LITERAL_STRING) {
String stringVal = lexer.stringVal();
lexer.nextToken();
return (T) createFactoryInstance(config, stringVal);
}
}
} catch (Exception ex) {
throw new JSONException(ex.getMessage(), ex);
}
}
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;
}
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) {
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) {
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) {
object = createInstance(parser, type);
if (object == null) {
fieldValues = new HashMap<String, Object>(this.fieldDeserializers.length);
}
childContext = parser.setContext(context, object, fieldName);
if (setFlags == null) {
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.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()));
}
}
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;
}
Method buildMethod = beanInfo.buildMethod;
if (buildMethod == null) {
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);
}
}
toJavaObject该方法是最主要字段转换实现方法:
public static <T> T cast(Object obj, Class<T> clazz, ParserConfig config){ if(obj == null){ if(clazz == int.class){ return (T) Integer.valueOf(0); } else if(clazz == long.class){ return (T) Long.valueOf(0); } else if(clazz == short.class){ return (T) Short.valueOf((short) 0); } else if(clazz == byte.class){ return (T) Byte.valueOf((byte) 0); } else if(clazz == float.class){ return (T) Float.valueOf(0); } else if(clazz == double.class){ return (T) Double.valueOf(0); } else if(clazz == boolean.class){ return (T) Boolean.FALSE; } return null; } if(clazz == null){ throw new IllegalArgumentException("clazz is null"); } if(clazz == obj.getClass()){ return (T) obj; } if(obj instanceof Map){ if(clazz == Map.class){ return (T) obj; } Map map = (Map) obj; if(clazz == Object.class && !map.containsKey(JSON.DEFAULT_TYPE_KEY)){ return (T) obj; } return castToJavaBean((Map<String,Object>) obj, clazz, config); } if(clazz.isArray()){ if(obj instanceof Collection){ Collection collection = (Collection) obj; int index = 0; Object array = Array.newInstance(clazz.getComponentType(), collection.size()); for(Object item : collection){ Object value = cast(item, clazz.getComponentType(), config); Array.set(array, index, value); index++; } return (T) array; } if(clazz == byte[].class){ return (T) castToBytes(obj); } } if(clazz.isAssignableFrom(obj.getClass())){ return (T) obj; } if(clazz == boolean.class || clazz == Boolean.class){ return (T) castToBoolean(obj); } if(clazz == byte.class || clazz == Byte.class){ return (T) castToByte(obj); } if(clazz == char.class || clazz == Character.class){ return (T) castToChar(obj); } if(clazz == short.class || clazz == Short.class){ return (T) castToShort(obj); } if(clazz == int.class || clazz == Integer.class){ return (T) castToInt(obj); } if(clazz == long.class || clazz == Long.class){ return (T) castToLong(obj); } if(clazz == float.class || clazz == Float.class){ return (T) castToFloat(obj); } if(clazz == double.class || clazz == Double.class){ return (T) castToDouble(obj); } if(clazz == String.class){ return (T) castToString(obj); } if(clazz == BigDecimal.class){ return (T) castToBigDecimal(obj); } if(clazz == BigInteger.class){ return (T) castToBigInteger(obj); } if(clazz == Date.class){ return (T) castToDate(obj); } if(clazz == java.sql.Date.class){ return (T) castToSqlDate(obj); } if(clazz == java.sql.Time.class){ return (T) castToSqlTime(obj); } if(clazz == java.sql.Timestamp.class){ return (T) castToTimestamp(obj); } if(clazz.isEnum()){ return (T) castToEnum(obj, clazz, config); } if(Calendar.class.isAssignableFrom(clazz)){ Date date = castToDate(obj); Calendar calendar; if(clazz == Calendar.class){ calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale); } else{ try{ calendar = (Calendar) clazz.newInstance(); } catch(Exception e){ throw new JSONException("can not cast to : " + clazz.getName(), e); } } calendar.setTime(date); return (T) calendar; } String className = clazz.getName(); if(className.equals("javax.xml.datatype.XMLGregorianCalendar")){ Date date = castToDate(obj); Calendar calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale); calendar.setTime(date); return (T) CalendarCodec.instance.createXMLGregorianCalendar(calendar); } if(obj instanceof String){ String strVal = (String) obj; if(strVal.length() == 0 // || "null".equals(strVal) // || "NULL".equals(strVal)){ return null; } if(clazz == java.util.Currency.class){ return (T) java.util.Currency.getInstance(strVal); } if(clazz == java.util.Locale.class){ return (T) toLocale(strVal); } if (className.startsWith("java.time.")) { String json = JSON.toJSONString(strVal); return JSON.parseObject(json, clazz); } } final ObjectDeserializer objectDeserializer = config.getDeserializers().get(clazz); if (objectDeserializer != null) { String str = JSON.toJSONString(obj); return JSON.parseObject(str, clazz); } throw new JSONException("can not cast to : " + clazz.getName()); }