mirror of
https://github.com/alibaba/fastjson.git
synced 2026-10-29 06:06:50 +08:00
bug fixed generic support. issue #998
This commit is contained in:
@@ -12,6 +12,7 @@ import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
|
||||
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
|
||||
import com.alibaba.fastjson.util.FieldInfo;
|
||||
import com.alibaba.fastjson.util.ParameterizedTypeImpl;
|
||||
import com.alibaba.fastjson.util.TypeUtils;
|
||||
|
||||
class ListTypeFieldDeserializer extends FieldDeserializer {
|
||||
|
||||
@@ -24,22 +25,11 @@ class ListTypeFieldDeserializer extends FieldDeserializer {
|
||||
|
||||
Type fieldType = fieldInfo.fieldType;
|
||||
Class<?> fieldClass= fieldInfo.fieldClass;
|
||||
if (fieldType instanceof ParameterizedType) {
|
||||
Type argType = ((ParameterizedType) fieldInfo.fieldType).getActualTypeArguments()[0];
|
||||
if (argType instanceof WildcardType) {
|
||||
WildcardType wildcardType = (WildcardType) argType;
|
||||
Type[] upperBounds = wildcardType.getUpperBounds();
|
||||
if (upperBounds.length == 1) {
|
||||
argType = upperBounds[0];
|
||||
}
|
||||
}
|
||||
this.itemType = argType;
|
||||
array = false;
|
||||
} else if (fieldClass.isArray()) {
|
||||
if (fieldClass.isArray()) {
|
||||
this.itemType = fieldClass.getComponentType();
|
||||
array = true;
|
||||
} else {
|
||||
this.itemType = Object.class;
|
||||
this.itemType = TypeUtils.getCollectionItemType(fieldType);
|
||||
array = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.parser.DefaultJSONParser;
|
||||
import com.alibaba.fastjson.parser.JSONToken;
|
||||
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
|
||||
import com.alibaba.fastjson.util.TypeUtils;
|
||||
|
||||
/**
|
||||
* @author wenshao[szujobs@hotmail.com]
|
||||
@@ -57,10 +58,7 @@ public class CollectionCodec implements ObjectSerializer, ObjectDeserializer {
|
||||
|
||||
Type elementType = null;
|
||||
if ((out.features & SerializerFeature.WriteClassName.mask) != 0) {
|
||||
if (fieldType instanceof ParameterizedType) {
|
||||
ParameterizedType param = (ParameterizedType) fieldType;
|
||||
elementType = param.getActualTypeArguments()[0];
|
||||
}
|
||||
elementType = TypeUtils.getCollectionItemType(fieldType);
|
||||
}
|
||||
|
||||
Collection<?> collection = (Collection<?>) object;
|
||||
@@ -168,24 +166,8 @@ public class CollectionCodec implements ObjectSerializer, ObjectDeserializer {
|
||||
throw new JSONException("create instane error, class " + rawClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
Type itemType = null;
|
||||
if (type instanceof ParameterizedType) {
|
||||
itemType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
} else {
|
||||
Class<?> clazz = null;
|
||||
if (type instanceof Class<?> //
|
||||
&& !(clazz = (Class<?>) type).getName().startsWith("java.")) {
|
||||
Type superClass = clazz.getGenericSuperclass();
|
||||
if (superClass instanceof ParameterizedType) {
|
||||
itemType = ((ParameterizedType) superClass).getActualTypeArguments()[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (itemType == null) {
|
||||
itemType = Object.class;
|
||||
}
|
||||
}
|
||||
|
||||
Type itemType = TypeUtils.getCollectionItemType(type);
|
||||
parser.parseArray(itemType, list, fieldName);
|
||||
|
||||
return (T) list;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.fastjson.serializer;
|
||||
|
||||
import com.alibaba.fastjson.util.TypeUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
@@ -36,10 +38,7 @@ public final class ListSerializer implements ObjectSerializer {
|
||||
|
||||
Type elementType = null;
|
||||
if (writeClassName) {
|
||||
if (fieldType instanceof ParameterizedType) {
|
||||
ParameterizedType param = (ParameterizedType) fieldType;
|
||||
elementType = param.getActualTypeArguments()[0];
|
||||
}
|
||||
elementType = TypeUtils.getCollectionItemType(fieldType);
|
||||
}
|
||||
|
||||
if (object == null) {
|
||||
|
||||
@@ -1336,6 +1336,34 @@ public class TypeUtils {
|
||||
: null;
|
||||
}
|
||||
|
||||
public static Type getCollectionItemType(Type fieldType) {
|
||||
Type itemType = null;
|
||||
Class<?> clazz = null;
|
||||
if (fieldType instanceof ParameterizedType) {
|
||||
Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
|
||||
|
||||
if (actualTypeArgument instanceof WildcardType) {
|
||||
WildcardType wildcardType = (WildcardType) actualTypeArgument;
|
||||
Type[] upperBounds = wildcardType.getUpperBounds();
|
||||
if (upperBounds.length == 1) {
|
||||
actualTypeArgument = upperBounds[0];
|
||||
}
|
||||
}
|
||||
|
||||
itemType = actualTypeArgument;
|
||||
} else if (fieldType instanceof Class<?> //
|
||||
&& !(clazz = (Class<?>) fieldType).getName().startsWith("java.")) {
|
||||
Type superClass = clazz.getGenericSuperclass();
|
||||
itemType = TypeUtils.getCollectionItemType(superClass);
|
||||
}
|
||||
|
||||
if (itemType == null) {
|
||||
itemType = Object.class;
|
||||
}
|
||||
|
||||
return itemType;
|
||||
}
|
||||
|
||||
// public static long fnv_hash(char[] chars) {
|
||||
// long hash = 0x811c9dc5;
|
||||
// for (int i = 0; i < chars.length; ++i) {
|
||||
|
||||
@@ -2,8 +2,10 @@ package com.alibaba.json.bvt.bug;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -15,7 +17,18 @@ public class Issue998 extends TestCase {
|
||||
assertNotNull(model);
|
||||
assertNotNull(model.items);
|
||||
assertEquals(1, model.items.size());
|
||||
assertEquals(123, model.items.get(0).id);
|
||||
assertEquals(123, model.items.get(0).getId());
|
||||
|
||||
String json = JSON.toJSONString(model, SerializerFeature.NotWriteRootClassName, SerializerFeature.WriteClassName);
|
||||
assertEquals("{\"items\":[{\"id\":123}]}", json);
|
||||
}
|
||||
|
||||
public void test_for_issue_1() throws Exception {
|
||||
Field field = Model.class.getField("items");
|
||||
List<Item> items = (List<Item> ) JSON.parseObject("[{\"id\":123}]", field.getGenericType());
|
||||
assertNotNull(items);
|
||||
assertEquals(1, items.size());
|
||||
assertEquals(123, items.get(0).id);
|
||||
}
|
||||
|
||||
public static class Model {
|
||||
@@ -23,6 +36,14 @@ public class Issue998 extends TestCase {
|
||||
}
|
||||
|
||||
public static class Item {
|
||||
public int id;
|
||||
private int id;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.alibaba.json.bvt.bug;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by wenshao on 16/01/2017.
|
||||
*/
|
||||
public class Issue998_private extends TestCase {
|
||||
public void test_for_issue() throws Exception {
|
||||
Model model = JSON.parseObject("{\"items\":[{\"id\":123}]}", Model.class);
|
||||
assertNotNull(model);
|
||||
assertNotNull(model.items);
|
||||
assertEquals(1, model.items.size());
|
||||
assertEquals(123, model.items.get(0).getId());
|
||||
|
||||
String json = JSON.toJSONString(model, SerializerFeature.NotWriteRootClassName, SerializerFeature.WriteClassName);
|
||||
assertEquals("{\"items\":[{\"id\":123}]}", json);
|
||||
}
|
||||
|
||||
public void test_for_issue_1() throws Exception {
|
||||
Field field = Model.class.getField("items");
|
||||
List<Item> items = (List<Item> ) JSON.parseObject("[{\"id\":123}]", field.getGenericType());
|
||||
assertNotNull(items);
|
||||
assertEquals(1, items.size());
|
||||
assertEquals(123, items.get(0).id);
|
||||
}
|
||||
|
||||
private static class Model {
|
||||
public List<? extends Item> items;
|
||||
}
|
||||
|
||||
private static class Item {
|
||||
private int id;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user