1、在使用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;
}
2、将下列json
数据转化为一个Result<Item>
对象
{
"data":{
"name":"username",
"value":"root"
},
"msg":"Success",
"ret":0
}
2.1、错误转化方法
// 方法1-编译器就报错了Cannot select parameterized type。
JSONObject.parseObject(json, Result<Item>.class);
// 方法2-执行没问题。但是没有Item类型信息,fastjson不可能跟你心有灵犀一点通知道该把data转为Item类型
SONObject.parseObject(json, Result.class);
2.2、正确转化方法
/**
* 将上述的Json串转化为对象
*/
private static <T> Result<T> parseResultV1(String json) {
return JSONObject.parseObject(json, new TypeReference<Result<T>>() {});
}
3、针对Result泛型进行动态的转化
3.1、错误方法
// 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>>() {});
}
3.2、正确的方法
TypeReference的构造器是可以传入参数的,
private static <T> Result<T> parseResultV2(String json, Class<T> clazz) {
return JSONObject.parseObject(json, new TypeReference<Result<T>>(clazz) {});
}
4、针对Result<List>泛型进行动态的转化
4.1、TypeReference的源码
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;
}
4.2、自己封装
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);
}
原创文章,作者:745907710,如若转载,请注明出处:https://blog.ytso.com/270841.html