SpringMVC
时,通常会定义通用类型与前端进行交互@Data public class Result<T> { private int ret; private String msg; private T data; }
@Data public class Item { private String name; private String value; }
json
数据转化为一个Result<Item>
对象{ "data":{ "name":"username", "value":"root" }, "msg":"Success", "ret":0 }
// 方法1-编译器就报错了Cannot select parameterized type。 JSONObject.parseObject(json, Result<Item>.class); // 方法2-执行没问题。但是没有Item类型信息,fastjson不可能跟你心有灵犀一点通知道该把data转为Item类型 SONObject.parseObject(json, Result.class);
/** * 将上述的Json串转化为对象 */ private static <T> Result<T> parseResultV1(String json) { return JSONObject.parseObject(json, new TypeReference<Result<T>>() {}); }
// java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to Item private static <T> Result<T> parseResultV1(String json) { return JSONObject.parseObject(json, new TypeReference<Result<T>>() {}); }
TypeReference的构造器是可以传入参数的,
private static <T> Result<T> parseResultV2(String json, Class<T> clazz) { return JSONObject.parseObject(json, new TypeReference<Result<T>>(clazz) {}); }
protected TypeReference(Type... actualTypeArguments) { Class<?> thisClass = this.getClass(); Type superClass = thisClass.getGenericSuperclass(); ParameterizedType argType = (ParameterizedType)((ParameterizedType)superClass).getActualTypeArguments()[0]; Type rawType = argType.getRawType(); Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0; for(int i = 0; i < argTypes.length; ++i) { if (argTypes[i] instanceof TypeVariable) { argTypes[i] = actualTypeArguments[actualIndex++]; if (actualIndex >= actualTypeArguments.length) { break; } } } Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); Type cachedType = (Type)classTypeCache.get(key); if (cachedType == null) { classTypeCache.putIfAbsent(key, key); cachedType = (Type)classTypeCache.get(key); } this.type = cachedType; }
TypeReference
无法处理嵌套的泛型(这里指的是类型参数未确定,而不是类似Result<List<Item>>
类型参数已经确定)。借用Fastjson
解析多级泛型的几种方式—使用class
文件来解析多级泛型里的方法,新增加一个专门处理List
类型的方法:
/** * 方法1:针对多个的情况 */ private <T> Result<List<T>> parseListResult(String json, Class<T> clazz) { return JSONObject.parseObject(json, buildType(Result.class, List.class, Item.class)); } private Type buildType(Type... types) { if (types == null && types.length == 0) { return null; } ParameterizedTypeImpl beforeType = null; if (types.length == 1) { beforeType = new ParameterizedTypeImpl(null, null, types[0]); return beforeType; } for (int i = types.length - 1; i > 0; i--) { beforeType = new ParameterizedTypeImpl( new Type[]{beforeType == null ? types[i] : beforeType}, null, types[i - 1]); } return beforeType; } /** * 方法2:针对Result<List<T>>这种情况 */ private static <T> Result<List<T>> parseListResult(String json, Class<T> clazz) { ParameterizedTypeImpl inner = new ParameterizedTypeImpl(new Type[]{clazz}, null, List.class); ParameterizedTypeImpl outer = new ParameterizedTypeImpl(new Type[]{inner}, null, Result.class); return JSONObject.parseObject(json, outer); }