我试图学习第一次使用Generics,这是一种相当复杂的方式。我也使用Jackson 2进行反序列化。
我每次都在回复陈述中。有人能告诉我这是不是错了?如果是这样,有什么更好的方法呢?
这是一个简单的示例类,用于演示这种情况:
class ResourceFactory <T extends Resource>{
List<T> getResources(String path)
{
ResourcesResponse rgRes = new ObjectMapper()
.readValue(response.body().byteStream(), ResourcesResponse.class)
return (List<T>)rgRes.resources
}
}
更新:
根据评论,这里是其他类主体外观的超简化示例。
class ResourceResponse {
List<Resource> resources
}
class ResourceGeneric extends Resource {
}
class ResourceTypeOne extends Resource {
public String typeOneOnlyProperty
}
class ResourceTypeTwo extends Resource {
public String typeTwoOnlyProperty
}
答案 0 :(得分:3)
class ResourcesResponse<T extends Resource> {
List<T> resources;
}
class ResourceFactory<T extends Resource> {
// Either of these should work; pick your constructor
private JavaType responseType;
private TypeReference<ResourcesResponse<T>> responseType;
// Option A
// Involves some boilerplate, but keeps the constructor simple
// Use: new ResourceFactory<ResourceTypeOne>(ResourceTypeOne.class)
ResourceFactory(Class<T> resourceType) {
this.responseType = TypeFactory.defaultInstance()
.constructParametricType(ResourcesResponse.class, resourceType);
}
// Option B
// Cleaner internally, but exposes implementation details
// Use: new ResourceFactory<ResourceTypeOne>(new TypeReference<ResourcesResponse<ResourceTypeOne>>() {})
ResourceFactory(TypeReference<ResourcesResponse<T>> responseType) {
this.responseType = responseType;
}
List<T> getResources(String path)
{
ResourcesResponse<T> rgRes = new ObjectMapper()
.readValue(response.body().byteStream(), responseType);
return rgRes.resources;
}
}
答案 1 :(得分:1)
由于类型擦除,故障快速技术是传递Resource子类:
public <T extends Resource> List<T> getResources(Class<T> resourceType, String path)
{
ResourcesResponse rgRes = new ObjectMapper()
.readValue(response.body().byteStream(), ResourcesResponse.class)
return Collections.checkedList(rgRes.resources, resourceType);
}
这可以确保您的代码具有此类不安全的强制转换,但不会添加其他类的值。
这不会“检查”原始列表
rgRes.resources.forEach(res -> resourceType.cast(res))
这不是一个简单的演员。