我想基于作为参数传递的泛型类,使用POJO序列化一些JSON。
Generic类应该扩展一个抽象类,以便我可以在结果数据结构上调用一些通用方法。
到目前为止,我已经知道了:
private <T extends TypeInterface> List<DBObject> getDataUsingJsonPath(String path, Class<T> type) {
TypeRef<List<T>> typeRef = new TypeRef<List<T>>() {};
Configuration configuration = Configuration
.builder()
.mappingProvider(new JacksonMappingProvider())
.jsonProvider(new JacksonJsonProvider())
.build();
List<T> items = JsonPath.using(configuration).parse(jsonString).read(path, typeRef);
result = items.getAggregations();
错误:
无法构造TypeInterface的实例,问题:抽象类型 要么需要映射到具体类型,要么具有自定义反序列化器, 或使用其他类型信息实例化
我试图告诉它扩展了TypeInterface,但是实际的Class是'type'...我在这里想念什么?
答案 0 :(得分:1)
编译器将编译new TypeRef<List<T>>() {};
作为对List<T extends TypeInterface>
的引用,而不是type
提供的元素类型。
JsonPath似乎不支持通过指定类进一步完善typeref。查看源代码,可以使用更扩展的库,例如guava,并进行以下修改:
TypeToken<T>
一样构造番石榴TypeRef<T>
,但是使用.where(new TypeParameter<T>() {}, type)
将类型变量精简为最终类型。包装器:
class TokenRef<T> extends TypeRef<T> {
private final TypeToken<T> token;
public TokenRef(TypeToken<T> token) {
super();
this.token = token;
}
@Override
public Type getType() {
return this.token.getType();
}
}
答案 1 :(得分:1)
快速解决方案:
private <T extends TypeInterface> List<DBObject> getDataUsingJsonPath(String path, Class<T> type) {
Configuration configuration = Configuration
.builder()
.mappingProvider(new JacksonMappingProvider())
.jsonProvider(new JacksonJsonProvider())
.build();
List<T> items = JsonPath.using(configuration).parse(jsonString).read(path, (Class<List<T>>) new ArrayList<T>().getClass());
这个想法是摆脱TypeRef<List<T>>
的作用,但会发出警告。
答案 2 :(得分:0)
这里有一些很好的答案,但是经过一番睡眠后,我选择将TypeRef更改为实际参数。
private <T extends TypeInterface> List<DBObject> getDataUsingJsonPath(String path, TypeRef<List<T>> type) {
然后我可以按预期迭代结果:
List<T> items = JsonPath.using(configuration).parse(responseString).read(path, type);
for(T item : items) {
// do generic TypeInterface stuff here
我不知道这是否是最好的,最正确的“通用”方式,但是到目前为止还不错,并且在阅读我认为的代码时基本上是有意义的。