我试图在一个方法中使用泛型,我将json反序列化为pojo,因此它可以返回任何对象类型.
这是我的代码:
private Bla(List<A> as, List<B> bs)
{
this.as = as;
this.bs = bs;
}
public static Bla from(JsonObject json)
{
return new Bla(Bla.<A>load(json, As), Bla.<B>load(json, Bs));
}
private static <T> List<T> load(JsonObject jsonObject, String param)
{
return jsonObject.getJsonArray(param).stream()
.map(Bla::getItem)
.collect(Collectors.toList());
}
private static <T> T getItem(Object json)
{
try {
return mapper.readValue(json.toString(), new TypeReference<T>() {
});
} catch (IOException e) {
throw new RuntimeException("Error parsing json items", e);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是.collect(Collectors.toList());似乎没有编译原因无法解析实例类型.
编译错误是:
Error:(43, 25) java: incompatible types: inference variable T has incompatible bounds
equality constraints: T
lower bounds: java.lang.Object
为了避免混淆我的例子A和B是Pojos
问候.
我们来看看这个方法:
private static <T> List<T> load(JsonObject jsonObject, String param)
{
return jsonObject.getJsonArray(param).stream()
.map(Bla::getItem)
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
最后一步的类型Collectors.toList()必须是List<T>,但要获得上一步的类型,Bla::getItem必须推断为T getItem.由于getItem是一种通用方法,因此需要一种类型约束传播的复杂模式,这显然比Java的类型推断将要处理的更多.要解决此问题,请使用提示帮助编译器:
.map(Bla::<T>getItem)
Run Code Online (Sandbox Code Playgroud)
(这个句法变体的功劳归于用户NándorElődFekete).
第二个问题是你的getItem方法:
private static <T> T getItem(Object json)
{
return mapper.readValue(json.toString(), new TypeReference<T>() {};
}
Run Code Online (Sandbox Code Playgroud)
TypeReference在这里使用没有帮助,因为T它不是具体类型.它将在编译器在此创建的匿名类中保持不确定状态,因此Jackson将不会从中获得任何有用的提示.你可以使用一个更简单的readValue签名,不需要TypeReference.