【发布时间】:2018-07-02 06:16:00
【问题描述】:
Jackson 2 ObjectMapper 类定义了许多通用方法,用于将 JSON 字符串、字节数组、文件等反序列化为给定的 Java 类型。
目标类型在这些方法的参数中给出。
例如。类型可以以Class<T> 的形式给出,就像在方法中一样
public <T> T readValue(String content, Class<T> valueType)
它返回相同的T 对象(因此是类型安全的)。
但它也可以以TypeReference<T> 的形式给出(可以编码复杂的泛型类型),因此可以构建例如。 new TypeReference<List<Long>> { } 告诉 ObjectMapper 输入需要反序列化为 long 列表——它可以传递,例如。进入方法:
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(String content, TypeReference valueTypeRef)
但该方法采用 raw TypeReference 而不是泛型 TypeReference<T>,因此需要手动向调用添加泛型参数:
objectMapper.<List<Long>>readValue(input, listOfLongs)
如果在提供的类型中出现错误,编译器将无法捕捉到。如果方法签名是,那将不是问题
public <T> T readValue(String content, TypeReference<T> valueTypeRef)
这将告诉编译器返回的值始终与提供的TypeReference 的泛型参数的类型相同,类似于它与Class<T> 的工作方式。
我的问题是——这种 API 背后的原因是什么? 为什么 Jackson 方法采用原始的 TypeReference?当返回的对象确实与TypeReference的泛型参数引用的类型不同时,是否存在任何有效情况?
PS:同样令我困惑的是,对应的convertValue 方法采用的不是原始类型,而是通配符:
public <T> T convertValue(Object fromValue, TypeReference<?> toValueTypeRef)
同样readValues:
public <T> MappingIterator<T> readValues(JsonParser p, TypeReference<?> valueTypeRef)
而readValue(JsonParser, TypeReference)实际上是takes a fully qualified generic parameter:
public <T> T readValue(JsonParser p, TypeReference<T> valueTypeRef)
【问题讨论】:
标签: java generics jackson jackson2