fastjson 反序列化“泛型二维数组”时,出现类型转换异常,Object[]类型不能转换成XXX[]类型

6tr1vspr  于 2021-11-27  发布在  Java
关注(0)|答案(1)|浏览(324)
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());
	}
}
nfg76nw0

nfg76nw01#

fastjson什么版本啊?我测试没问题

相关问题