1、测试代码 UserTest.java
@test
public void testGenericArrayArray2() throws Exception{
List list = new ArrayList<>();
list.add("robin");
Object[] args = new Object[]{new List[][]{new List[]{list}}};
String text = JSON.toJSONString(args);
Class clazz = User.class;
Method method = clazz.getMethod("testGenericArrayArray2", List[][].class);
Type[] types = method.getGenericParameterTypes();
List argList = JSON.parseArray(text, types);
Object res = new User().testGenericArrayArray2((List[][]) argList.get(0));
System.out.println(res);
}
2、相关类User.java
public class User{
public List[][] testGenericArrayArray2(List[][] res){
return res;
}
}
3、异常信息
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [[Ljava.util.List;
at org.jsirenia.json.JSONTest.testGenericArrayArray2(JSONTest.java:125)
4、原因
JavaObjectDeserializer类deserialze方法
if (componentType instanceof Class) {
componentClass = (Class) componentType;
Object[] array = (Object[]) Array.newInstance(componentClass, list.size());
list.toArray(array);
return (T) array;
} else {
return (T) list.toArray();
}
返回的始终是Object[]类型。
5、我的解决办法,写了一个工具类
public static Object[] parseJSONForArgs(Method method,String argsJSONArray){
Class<?>[] pts = method.getParameterTypes();
Type[] argTypes = method.getGenericParameterTypes();
List<Object> list = JSON.parseArray(argsJSONArray,argTypes);
Object[] args = new Object[list.size()];
/*JavaObjectDeserializer类的deserialze方法存在缺陷,
* 对于数组元素为数组类型的情况,反序列化时,反序列化后的元素类型固定为Object[]类型,会造成类型转换异常。
* */
for(int i=0;i<list.size();i++){
if(pts[i].isArray()){
args[i] = CollectionUtil.toArray(list.get(i), pts[i].getComponentType());
}else{
args[i] = list.get(i);
}
}
return args;
}
6、相关工具类
public class CollectionUtil {
//集合转数组,或者数组转数组。支持嵌套,比如Object[][]类型转Map<String,String>[][],前提是元素的值真的是Map类型的。
//这个可以用来解决fastjson的一个bug
public static <T> T[] toArray(Object collection,Class<T> componentType){
if(collection==null){
return null;
}
Class<?> clazz = collection.getClass();
if(clazz.isArray()){
int len = Array.getLength(collection);
T[] array = (T[]) Array.newInstance(componentType,len);
Object v = null;
Class<?> vclazz = null;
for(int i=0;i<len;i++){
v = Array.get(collection, i);
vclazz = v.getClass();
if(vclazz.isArray() || TypeUtil.isCollection(vclazz)){
Array.set(array, i, toArray(v, componentType.getComponentType()));
}else{
Array.set(array, i, Array.get(collection, i));
}
}
return array;
}
if(TypeUtil.isCollection(clazz)){
Collection<?> co = (Collection<?>) collection;
T[] array = (T[]) Array.newInstance(componentType,co.size());
return co.toArray(array);
}
throw new RuntimeException("不支持的类型:"+clazz.getName());
}
}
1条答案
按热度按时间nfg76nw01#
fastjson什么版本啊?我测试没问题