This repository was archived by the owner on Oct 23, 2024. It is now read-only.
This repository was archived by the owner on Oct 23, 2024. It is now read-only.
范型多级别继承的时候, 反序列化会无法精准解析 #2397
Open
Description
之前也提过这个issue,但今天又看了一下发现提的不太好理解。 现在关闭之前的issue重新提一下:
这事最高父类:
public class SuperBaseReply<T> {
private List<T> items;
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
}
这是第二层父类
public class BaseReply<T>extends SuperBaseReply<T> {
}
这是一个简单的pojo
public class Msg implements Serializable{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Msg(int id, String name) {
this.id = id;
this.name = name;
}
public Msg(){
}
}
这是最终协议类
public class TestReply extends BaseReply<Msg> {
}
测试代码如下:
String jsonStr = "{"items":[{"id":1,"name":"kata"},{"id":2,"name":"kata2"}]}";
TestReply testReply = JSON.parseObject(jsonStr, new TypeReference() {});
Assert.assertEquals(testReply.getItems().get(0).getId() , 1);
结果报错:
java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.babyfs.servicetk.test.api.Msg
at com.babyfs.servicetk.test.FastJsonTest.test2LayerDeserilize(FastJsonTest.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
跟进去看了一下版本(1.2.56):
发现可能的问题如下:
com.alibaba.fastjson.util.FieldInfo(323行)类中在分析范型的时候考虑的不够全面
代码如下:
private static boolean getArgument(Type[] typeArgs, TypeVariable[] typeVariables, Type[] arguments) {
if (arguments == null || typeVariables.length == 0) {
return false;
}
boolean changed = false;
for (int i = 0; i < typeArgs.length; ++i) {
Type typeArg = typeArgs[i];
if (typeArg instanceof ParameterizedType) {
ParameterizedType p_typeArg = (ParameterizedType) typeArg;
Type[] p_typeArg_args = p_typeArg.getActualTypeArguments();
boolean p_changed = getArgument(p_typeArg_args, typeVariables, arguments);
if (p_changed) {
typeArgs[i] = new ParameterizedTypeImpl(p_typeArg_args, p_typeArg.getOwnerType(), p_typeArg.getRawType());
changed = true;
}
} else if (typeArg instanceof TypeVariable) {
for (int j = 0; j < typeVariables.length; ++j) {
if (typeArg.equals(typeVariables[j])) {//typeVariables[j]获取的是BaseReply的T,然而范型的持有field在SuperBaseReply中,所以这里肯定是不等于,于是无法正确的设定范型类
typeArgs[i] = arguments[j];
changed = true;
}
}
}
}
return changed;
}
Metadata
Metadata
Assignees
Labels
No labels
Activity
Add testcase for issue alibaba#2397