bug fixed generic support. issue #998

This commit is contained in:
wenshao
2017-01-16 23:52:12 +08:00
parent 43fed87236
commit ca5f8a3c4c
6 changed files with 109 additions and 41 deletions
@@ -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;
}
}
}