扩展时,Jackson TypeReference是否起作用?
以下摘录是不言而喻的。您可以看到类型信息没有被擦除,但是映射器没有得到类型信息。我的猜测是杰克逊不允许这样做,对吧?如果我直接传递TypeReference,它将正确反序列化。
public class AgentReq<T> extends TypeReference<AgentResponse<T>> {...}mapper.readValue(reader, new AgentReq<Map<String, Set<Whatever>>>());
如果这样做,它也将不起作用:
public class AgentReq<T> { public TypeReference<AgentResponse<T>> getTypeRef() {
return new TypeReference<AgentResponse<T>>() {};
}
}
mapper.readValue(reader, new AgentReq<Map<String, Set<Whatever>>>()).getTypeRef();
我正在使用2.1.5版。
编辑:供将来参考,在解决问题时不要低估TypeReference构造函数。在这里,您可以直接查看它是否能够检索类型信息。答案是否定的,您不能扩展TypeReference并期望它能工作,甚至不能重写其getType()方法并向其提供从类中解析的类型信息,因为您所能获得的只是getClass()。
getGenericSuperClass()…你不能做getClass()。getGenericClass()
回答:
您需要了解TypeReference
作品的运作方式。为此,我们进入源代码
protected TypeReference(){
Type superClass = getClass().getGenericSuperclass();
if (superClass instanceof Class<?>) { // sanity check, should never happen
throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
}
...
_type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
该Class#getGenericSuperclass()
javadoc的状态
返回表示该类表示的实体的直接超类的Type(类,接口,原始类型或void)。
如果超类是参数化类型,则返回的Type对象必须准确反映源代码中使用的实际类型参数。
换句话说,如果我们能够做到new
TypeReference()(我们不能做到,那是抽象的),它将返回Class
该类的实例Object
。但是,使用匿名类(从类型扩展)
new TypeReference<String>(){}
创建的实例的直接超类是参数化类型TypeReference
,根据javadoc,我们应该获得一个Type
实例,该实例可以
准确反映源代码中使用的实际类型参数 :
TypeReference<String>
然后您可以从中获得参数化类型getActualTypeArguments()[0])
,并返回String
。
让我们以使用匿名类和子类进行可视化为例
public class Subclass<T> extends TypeReference<AgentResponse<T>>{ public Subclass() {
System.out.println(getClass().getGenericSuperclass());
System.out.println(((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
}
跑步
new Subclass<String>();
版画
com.fasterxml.jackson.core.type.TypeReference<Test.AgentResponse<T>>Test.AgentResponse<T>
符合javadoc规则。Test.AgentResponse<T>
是源代码中实际的参数化类型。现在,如果相反,我们有
new Subclass<String>(){}; // anonymous inner class
我们得到结果
Test.Subclass<java.lang.String>class java.lang.String
这也符合要求。现在,内部类直接从源类中扩展了,该内部类Subclass
由其参数进行参数化String
。
您会注意到,使用Subclass
匿名内部类,我们丢失了有关AgentResponse
泛型类型的信息。这是不可避免的。
注意
reader = new StringReader("{\"element\":{\"map-element\":[{\"name\":\"soto\", \"value\": 123}]}}");obj = mapper.readValue(reader, new AgentReq<Map<String, Set<Whatever>>>());
将编译并运行,但是类型AgentReq<Map<String,
Set<Whatever>>>将丢失。Jackson将使用默认类型来序列化JSON。的element
将被反序列化作为AgentResponse
,而map-
element将被反序列化作为Map
和JSON数组作为ArrayList
。
以上是 扩展时,Jackson TypeReference是否起作用? 的全部内容, 来源链接: utcz.com/qa/429144.html