完美解决fastJson泛型多层级嵌套,类型转化错误
先把实体类上了再说:
import lombok.Data;
@Data
public class Man {
private String name;
private String pass;
public Man(String name, String pass) {
this.name = name;
this.pass = pass;
}
}
然后把result结果封装类上了:
import lombok.Data;
/**
* @author yangwulang
*/
@Data
public class Results<T> {
private T data;
}
注意:我们一般会这样解析json数据
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
/**
* @author yangwulang
*/
public class Pp {
public Results call(String jsons) {
TypeReference<Results<Man>> typeReference = new TypeReference<Results<Man>>(s()) {};
return JSON.parseObject(jsons, typeReference);
}
}
但是写多了,就觉得很厌烦,然后会采用泛型,问题就来了
我一般会这么写
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
/**
* @author yangwulang
*/
public class Pp<T> {
public Results<T> call(String jsons) {
TypeReference<Results<T>> typeReference = new TypeReference<Results<T>>() {};
return JSON.parseObject(jsons, typeReference);
}
}
然后就这么运行
import top.yangwulang.ge.Man;
import top.yangwulang.ge.Pp;
import top.yangwulang.ge.Results;
import java.util.List;
/**
* Hello world!
*
* @author yangwulang
*/
public class AopTest {
public static void main(String[] args) {
Pp<List<Man>> listPp = new Pp<List<Man>>(){};
Results<List<Man>> call = listPp.call("{\"data\":[{\"name\":\"aaa\",\"pass\":\"bb\"},{\"name\":\"2aa\",\"pass\":\"2bb\"}]}");
call.getData().forEach(System.out::println);
}
}
就会哦豁
Exception in thread "main" java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to top.yangwulang.ge.Man
的出现一个转换错误
这是为啥呢?上面写的不都没有出错吗?
经过一步步百度分析,问哥哥求姐姐的,找到了一篇博客
https://www.cnblogs.com/liqipeng/p/9148545.html
连接直接给大家贴上,点我直达
至于具体解析看博客,反正我是没太看懂他写的代码,但是在他博客里找到一句对我有用的代码
private static <T> Result<T> parseResultV2(String json, Class<T> clazz) {
return JSONObject.parseObject(json, new TypeReference<Result<T>>(clazz) {
});
}
也就是这玩意,他的V5,原来这玩意可以传参,那我们试着读下FastJson源码:
/**
* @since 1.2.9
* @param actualTypeArguments
*/
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 &&
actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
}
// fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = TypeUtils.checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
}
// 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
if(argTypes[i] instanceof ParameterizedType) {
argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
}
}
Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
Type cachedType = classTypeCache.get(key);
if (cachedType == null) {
classTypeCache.putIfAbsent(key, key);
cachedType = classTypeCache.get(key);
}
type = cachedType;
}
对,就是这段,顺着他的思想,老子直接就是穿个他两个参数List.class,Man.class这次不会报错了吧,(永远别这么想,你是摆脱不了墨菲定律的)还是报一样的错误,(sdfjalsdflashiofnsdklfXXXXXOOOOO),
大爷的,two days later,看着稀烂的代码,不还是要把他jiu(揪)过来,又是百度分析,这次不直接找fastJson了,劳资直接搜嵌套,不知从哪篇博客搜索出来的,((ParameterizedType) XXX.getClass().getGenericSuperclass()).getActualTypeArguments();就是这段可以获得里面的类型,刚刚好这个P返回的还是一个数组,结果就是你们知道的
代码最终的形态是
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author yangwulang
*/
public class Pp<T> {
public Results<T> call(String jsons) {
TypeReference<Results<T>> typeReference = new TypeReference<Results<T>>(s()) {};
return JSON.parseObject(jsons, typeReference);
}
//写不写方法都无所谓,最主要的是要拿到这个类上的类型
public Type[] s(){
return ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments();
}
}
然后就没然后了,感谢大家的收看,结果给大家看下
E:\java\bin\java.exe -javaagent:E:\JBIDE\apps\IDEA-U\ch-0\193.6494.35\lib\idea_rt.jar=53687:E:\JBIDE\apps\IDEA-U\ch-0\193.6494.35\bin -Dfile.encoding=UTF-8 -classpath E:\java\jre\lib\charsets.jar;E:\java\jre\lib\deploy.jar;E:\java\jre\lib\ext\access-bridge-64.jar;E:\java\jre\lib\ext\cldrdata.jar;E:\java\jre\lib\ext\dnsns.jar;E:\java\jre\lib\ext\jaccess.jar;E:\java\jre\lib\ext\jfxrt.jar;E:\java\jre\lib\ext\localedata.jar;E:\java\jre\lib\ext\nashorn.jar;E:\java\jre\lib\ext\sunec.jar;E:\java\jre\lib\ext\sunjce_provider.jar;E:\java\jre\lib\ext\sunmscapi.jar;E:\java\jre\lib\ext\sunpkcs11.jar;E:\java\jre\lib\ext\zipfs.jar;E:\java\jre\lib\javaws.jar;E:\java\jre\lib\jce.jar;E:\java\jre\lib\jfr.jar;E:\java\jre\lib\jfxswt.jar;E:\java\jre\lib\jsse.jar;E:\java\jre\lib\management-agent.jar;E:\java\jre\lib\plugin.jar;E:\java\jre\lib\resources.jar;E:\java\jre\lib\rt.jar;D:\IDEAProject\spring-demo\demo-aop\target\classes;F:\apache\apache-maven-3.6.3\repository\org\projectlombok\lombok\1.16.8\lombok-1.16.8.jar;F:\apache\apache-maven-3.6.3\repository\org\springframework\spring-core\4.3.7.RELEASE\spring-core-4.3.7.RELEASE.jar;F:\apache\apache-maven-3.6.3\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;F:\apache\apache-maven-3.6.3\repository\org\springframework\spring-beans\4.3.7.RELEASE\spring-beans-4.3.7.RELEASE.jar;F:\apache\apache-maven-3.6.3\repository\org\springframework\spring-context\4.3.7.RELEASE\spring-context-4.3.7.RELEASE.jar;F:\apache\apache-maven-3.6.3\repository\org\springframework\spring-expression\4.3.7.RELEASE\spring-expression-4.3.7.RELEASE.jar;F:\apache\apache-maven-3.6.3\repository\org\springframework\spring-aop\4.3.7.RELEASE\spring-aop-4.3.7.RELEASE.jar;F:\apache\apache-maven-3.6.3\repository\org\springframework\spring-aspects\4.3.7.RELEASE\spring-aspects-4.3.7.RELEASE.jar;F:\apache\apache-maven-3.6.3\repository\org\aspectj\aspectjweaver\1.8.9\aspectjweaver-1.8.9.jar;F:\apache\apache-maven-3.6.3\repository\com\alibaba\fastjson\1.2.49\fastjson-1.2.49.jar;F:\apache\apache-maven-3.6.3\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;F:\apache\apache-maven-3.6.3\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;F:\apache\apache-maven-3.6.3\repository\org\slf4j\slf4j-nop\1.7.25\slf4j-nop-1.7.25.jar top.yangwulang.AopTest
Man(name=aaa, pass=bb)
Man(name=2aa, pass=2bb)
Process finished with exit code 0
=======================================================
还有很重要的一步
搞得我调试了一下午。。。。。
public static void main(String[] args) {
Pp<Man> pp = new Pp<Man>(){};
}
这个对象必须得这样子new才能获得这个泛型!!!!!!!
当中俺还有有许多不正确的请大家指正
本文详细介绍了在使用fastJson时遇到的泛型多层级嵌套导致的类型转化错误问题,通过一步步的排查和学习,最终找到了解决办法。作者分享了关键的代码片段,并提醒了一个重要的调试注意事项。

3868

被折叠的 条评论
为什么被折叠?



