Skip to content

Commit

Permalink
improved JSONObject.toJavaObject performance
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Apr 9, 2019
1 parent b06f717 commit 7b416fa
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
24 changes: 24 additions & 0 deletions src/main/java/com/alibaba/fastjson/JSONObject.java
Expand Up @@ -586,4 +586,28 @@ protected void readStreamHeader() throws IOException, StreamCorruptedException {

}
}

public <T> T toJavaObject(Class<T> clazz) {
if (clazz == Map.class) {
return (T) this;
}

if (clazz == Object.class && !containsKey(JSON.DEFAULT_TYPE_KEY)) {
return (T) this;
}

return TypeUtils.castToJavaBean(this, clazz, ParserConfig.getGlobalInstance());
}

public <T> T toJavaObject(Class<T> clazz, ParserConfig config, int features) {
if (clazz == Map.class) {
return (T) this;
}

if (clazz == Object.class && !containsKey(JSON.DEFAULT_TYPE_KEY)) {
return (T) this;
}

return TypeUtils.castToJavaBean(this, clazz, config);
}
}
Expand Up @@ -1284,12 +1284,59 @@ public Object createInstance(Map<String, Object> map, ParserConfig config) //
}

final FieldInfo fieldInfo = fieldDeser.fieldInfo;
Field field = fieldDeser.fieldInfo.field;
Type paramType = fieldInfo.fieldType;


if (paramType == boolean.class) {
if (value == Boolean.FALSE) {
field.setBoolean(object, false);
continue;
}

if (value == Boolean.TRUE) {
field.setBoolean(object, true);
continue;
}
} else if (paramType == int.class) {
if (value instanceof Number) {
field.setInt(object, ((Number) value).intValue());
continue;
}
} else if (paramType == long.class) {
if (value instanceof Number) {
field.setLong(object, ((Number) value).longValue());
continue;
}
} else if (paramType == float.class) {
if (value instanceof Number) {
field.setFloat(object, ((Number) value).floatValue());
continue;
}
} else if (paramType == double.class) {
if (value instanceof Number) {
field.setDouble(object, ((Number) value).doubleValue());
continue;
} else if (value instanceof String) {
double doubleValue = Double.parseDouble((String) value);
field.setDouble(object, doubleValue);
continue;
}
} else if (value != null && paramType == value.getClass()) {
field.set(object, value);
continue;
}


String format = fieldInfo.format;
if (format != null && paramType == java.util.Date.class) {
value = TypeUtils.castToDate(value, format);
} else {
value = TypeUtils.cast(value, paramType, config);
if (paramType instanceof ParameterizedType) {
value = TypeUtils.cast(value, (ParameterizedType) paramType, config);
} else {
value = TypeUtils.cast(value, paramType, config);
}
}

fieldDeser.setValue(object, value);
Expand Down
42 changes: 41 additions & 1 deletion src/main/java/com/alibaba/fastjson/util/TypeUtils.java
Expand Up @@ -1148,6 +1148,33 @@ public static <T> T cast(Object obj, Type type, ParserConfig mapping){
@SuppressWarnings({"rawtypes", "unchecked"})
public static <T> T cast(Object obj, ParameterizedType type, ParserConfig mapping){
Type rawTye = type.getRawType();

if(rawTye == List.class || rawTye == ArrayList.class){
Type itemType = type.getActualTypeArguments()[0];
if(obj instanceof List){
List listObj = (List) obj;
List arrayList = new ArrayList(listObj.size());

for (int i = 0; i < listObj.size(); i++) {
Object item = listObj.get(i);

Object itemValue;
if (itemType instanceof Class) {
if (item != null && item.getClass() == JSONObject.class) {
itemValue = ((JSONObject) item).toJavaObject((Class<T>) itemType, mapping, 0);
} else {
itemValue = cast(item, (Class<T>) itemType, mapping);
}
} else {
itemValue = cast(item, itemType, mapping);
}

arrayList.add(itemValue);
}
return (T) arrayList;
}
}

if(rawTye == Set.class || rawTye == HashSet.class //
|| rawTye == TreeSet.class //
|| rawTye == Collection.class //
Expand All @@ -1165,11 +1192,24 @@ public static <T> T cast(Object obj, ParameterizedType type, ParserConfig mappin
}
for(Iterator it = ((Iterable) obj).iterator(); it.hasNext(); ){
Object item = it.next();
collection.add(cast(item, itemType, mapping));

Object itemValue;
if (itemType instanceof Class) {
if (item != null && item.getClass() == JSONObject.class) {
itemValue = ((JSONObject) item).toJavaObject((Class<T>) itemType, mapping, 0);
} else {
itemValue = cast(item, (Class<T>) itemType, mapping);
}
} else {
itemValue = cast(item, itemType, mapping);
}

collection.add(itemValue);
}
return (T) collection;
}
}

if(rawTye == Map.class || rawTye == HashMap.class){
Type keyType = type.getActualTypeArguments()[0];
Type valueType = type.getActualTypeArguments()[1];
Expand Down

0 comments on commit 7b416fa

Please sign in to comment.