Java erases normally the Generics
data on compilation, but there is a possibility to get that information (the Jackson ObjectMapper
does that pretty well).
My Problem: I have a Class with a property of List:
public class User {
public List<Long> listProp;//it is public only to keep the example simple
}
How can I get the correct TypeReference
(or JavaType
?) so that I can map programatically a JSON String to the correct List Type, having the instance of the Class
class (User.class) and the property name (listProp)? What I mean is this:
TypeReference typeReference = ...;//how to get the typeReference?
List<Long> correctList = om.readValue(jsonEntry.getValue(), typeReference);//this should return a List<Long> and not eg. a List<Integer>
Have you tried the mappers constructType method?
Type genericType = User.class.getField("listProp").getGenericType();
List<Long> correctList = om.readValue(jsonEntry.getValue(), om.constructType(genericType));
jackson use TypeReference to construct generic type
TypeReference typeReference =new TypeReference<List<Long>>(){}
jackson use JavaType to construct generic type
JavaType jt = om.getTypeFactory().constructArrayType(Long.class);
jackson support three types
i like use JavaType, it is more clear for generic type, for normal object use Class
Perhaps a less exotic approach to deserializing a generic type is to wrap it inside a concrete type:
class ListLongWrapper extends ArrayList<Long> {} // package scope
... or ...
static class ListLongWrapper extends ArrayList<Long> {} // class scope
then
String jsonStr = objMapper.writeValueAsString(user1.listProp); // serialize
user2.listProp = objMapper.readValue(jsonStr,ListLongWrapper.class); // deserialize
Notice that extends
requires a class type (here I used ArrayList
) instead of the interface List
.
This suggests an even more direct approach for the given example -- User
is already a wrapper (and listProp
is public
):
public class User {
public List<Long> listProp;
}
then
String jsonStr = objMapper.writeValueAsString(user1); // serialize
var user2 = objMapper.readValue(jsonStr,User.class); // deserialize
In this case, you can use the interface List
as-is as a field type within the wrapping class, but this means you have no control over the concrete type that Jackson will use.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.