通用方法和JSON

时间:2017-06-07 23:26:03

标签: java json generics mapping

我编写了泛型方法,它返回一些对象的列表,例如Orders。我的问题是为什么在第二个非泛型方法中它返回正确的Orders列表,第一个方法(泛型)返回linkedHashMaps而不是Orders的列表?

通用:

 private <T> List<T> mapObjectsToList(String objectsListInJson) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    TypeReference<List<T>> mapType = new TypeReference<List<T>>() {
    };
    return objectMapper.readValue(objectsListInJson, mapType);
}

非通用:

private List<Order> mapObjectsToList(String objectsListInJson) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    TypeReference<List<Order>> mapType = new TypeReference<List<Order>>() {
    };
    return objectMapper.readValue(objectsListInJson, mapType);
}

通用方法返回: LinkedHashMap

3 个答案:

答案 0 :(得分:0)

因为在非通用方法中,您明确表示要添加Order

在您发送回objects的通用版中,这些版本必须属于Order类型。

在任何情况下,它都会返回List

答案 1 :(得分:0)

问题是你不能通过简单地声明它来传递一个类型参数。

类型参数被删除,因此在您的通用函数<T>中不存在,因此即使类型引用也无法传达此类信息。

您应该使用类的实际引用构建类型引用,并将类型引用传递给方法,如下所示:

List<Composite> out = mapObjectsToList(in, new TypeReference<List<Composite>>() {});

或......

事先知道您正在使用TypeFactory

完全反序列化T列表
private static <T> List<T> mapObjectsToList(Reader objectsListInJson, Class<T> clazz) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    CollectionLikeType typeref = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, clazz);
    return objectMapper.readValue(objectsListInJson, typeref);
}

并称之为:

List<Composite> out = mapObjectsToList(in, Composite.class);

答案 2 :(得分:0)

问题是泛型类型变量T没有绑定到任何具体类型,因此编译器将其视为Object。所以:

TypeReference<List<T>> mapType = new TypeReference<List<T>>() {};

实际上是:

TypeReference<List<Object>> mapType = new TypeReference<List<Object>>() {};

ObjectMapper无法收集有关要反序列化的对象的具体类型的信息时,默认为LinkedHashMap

如果您希望能够在运行时反序列化为泛型类型,则应将TypeReference类型标记作为参数传递给mapObjectsToList方法:

// Make this a singleton, i.e. don't create a new instance on every call!
ObjectMapper objectMapper = new ObjectMapper();

private <T> List<T> mapObjectsToList(
        String objectsListInJson, 
        TypeReference<List<T>> mapType) throws IOException {

    return objectMapper.readValue(objectsListInJson, mapType);
}

然后使用以上方法:

List<Order> orders = mapObjectsToList(
    stringWithTheJSON, 
    new TypeReference<List<Order>> {});

在旁注中,我已将ObjectMapper objectMapper = new ObjectMapper()语句移到方法之外。整个应用程序中应该只有一个ObjectMapper实例,除非您需要不同的配置来序列化/反序列化。