JSON 使用 TypeReference 的泛型反序列化器
JSON deserializer with generic type using TypeReference
我正在尝试推广此方法:
public EventStream<Greeting> deserialize(String value){
ObjectMapper mapper = new ObjectMapper();
EventStream<Greeting> data = null;
try {
data = new ObjectMapper().readValue(value, new TypeReference<EventStream<Greeting>>() {});
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
其中 EventStream 是:
public class EventStream<T> {
private EventHeaders headers;
@JsonDeserialize
private T payload;
}
我想要的是在反序列化方法中用泛型替换特定的对象问候语。
我试过这个:
public <T> EventStream<T> deserialize(String value){
ObjectMapper mapper = new ObjectMapper();
EventStream<T> data = null;
try {
data = new ObjectMapper().readValue(value, new TypeReference<EventStream<T>>() {});
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
但是 EventStream 结果中的负载被反序列化为 LinkedHashMap。似乎 TypeReference 忽略了通用类型。
任何想法?
谢谢
您在这里遇到的是一个常见的问题,由称为类型擦除的东西引起,java 实现泛型的方式。
Type erasure can be explained as the process of enforcing type
constraints only at compile time and discarding the element type
information at runtime. [1]
所以当你尝试反序列化你的对象时,类型 T 是未知的,它只是被视为 Object
并且反序列化结果将默认默认为 Map
(LinkedHashMap
准确地说)。
您可以通过将您的 targetClass 作为附加参数传递给函数调用来使您的方法通用:
public <T> EventStream<T> deserialize(String value, Class<T> targetClass)
然后使用映射器的 TypeFactory 来创建此 targetClass 的类型
JavaType type = mapper.getTypeFactory().constructParametricType(EventStream.class, targetClass);
您可以将其传递给 readValue 方法:
data = mapper.readValue(value, type);
完整代码:
public <T> EventStream<T> deserialize(String value, Class<T> targetClass){
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory()
.constructParametricType(EventStream.class, targetClass);
try {
return mapper.readValue(value, type);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
我正在尝试推广此方法:
public EventStream<Greeting> deserialize(String value){
ObjectMapper mapper = new ObjectMapper();
EventStream<Greeting> data = null;
try {
data = new ObjectMapper().readValue(value, new TypeReference<EventStream<Greeting>>() {});
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
其中 EventStream 是:
public class EventStream<T> {
private EventHeaders headers;
@JsonDeserialize
private T payload;
}
我想要的是在反序列化方法中用泛型替换特定的对象问候语。
我试过这个:
public <T> EventStream<T> deserialize(String value){
ObjectMapper mapper = new ObjectMapper();
EventStream<T> data = null;
try {
data = new ObjectMapper().readValue(value, new TypeReference<EventStream<T>>() {});
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
但是 EventStream 结果中的负载被反序列化为 LinkedHashMap。似乎 TypeReference 忽略了通用类型。 任何想法? 谢谢
您在这里遇到的是一个常见的问题,由称为类型擦除的东西引起,java 实现泛型的方式。
Type erasure can be explained as the process of enforcing type constraints only at compile time and discarding the element type information at runtime. [1]
所以当你尝试反序列化你的对象时,类型 T 是未知的,它只是被视为 Object
并且反序列化结果将默认默认为 Map
(LinkedHashMap
准确地说)。
您可以通过将您的 targetClass 作为附加参数传递给函数调用来使您的方法通用:
public <T> EventStream<T> deserialize(String value, Class<T> targetClass)
然后使用映射器的 TypeFactory 来创建此 targetClass 的类型
JavaType type = mapper.getTypeFactory().constructParametricType(EventStream.class, targetClass);
您可以将其传递给 readValue 方法:
data = mapper.readValue(value, type);
完整代码:
public <T> EventStream<T> deserialize(String value, Class<T> targetClass){
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory()
.constructParametricType(EventStream.class, targetClass);
try {
return mapper.readValue(value, type);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}