我试图在一个方法中使用泛型,我将json反序列化为pojo,因此它可以返回任何对象类型。
这是我的代码:
$documents = $collectionHandler->all($collectionId);
var_dump($documents);
问题是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);
}
}
似乎不是编译原因无法解析实例类型。
编译错误是:
Error:(43, 25) java: incompatible types: inference variable T has incompatible bounds equality constraints: T lower bounds: java.lang.Object
为避免混淆我的例子A和B是Pojos
问候。
答案 0 :(得分:8)
让我们来看看这个方法:
private static <T> List<T> load(JsonObject jsonObject, String param)
{
return jsonObject.getJsonArray(param).stream()
.map(Bla::getItem)
.collect(Collectors.toList());
}
最后一步的类型Collectors.toList()
必须为List<T>
,但要获得上一步的类型,Bla::getItem
必须推断为T getItem
。由于getItem
是一种通用方法,因此需要一种类型约束传播的复杂模式,这显然比Java的类型推断所能处理的更多。要解决此问题,请使用提示帮助编译器:
.map(Bla::<T>getItem)
(此语法变体的功能归功于用户NándorElődFekete)。
第二个问题是您的getItem
方法:
private static <T> T getItem(Object json)
{
return mapper.readValue(json.toString(), new TypeReference<T>() {};
}
这里使用TypeReference
没有用,因为T
不是具体类型。它将在编译器在此创建的匿名类中保持不确定状态,因此Jackson将不会从中获得任何有用的提示。您可以使用更简单的readValue
签名,但不会使用TypeReference
。