首页 > 解决方案 > Java 未经检查的赋值

问题描述

我定义了一个函数,它返回实现PaginationData接口的任何对象的通用列表

private <T> List<T> paginate(int pageNumber, int pageSize, int totalAvailable, PaginatedResponse paginatedResponse, String url) {
   List<T> listOfObjects = new ArrayList();
        while (pageNumber * pageSize <= totalAvailable) {
           paginatedResponse = sendRequest(url + "?pageNumber=" + pageNumber, paginatedResponse.getClass());

           listOfObjects.addAll(paginatedResponse
           .getPaginationData()
           .getPaginatedObjectsList());
 
           pageNumber++;
   }
  return listOfObjects;
}

和这样定义的 PaginatedResponse

public interface PaginatedResponse {

    Pagination getPagination();

    PaginationData getPaginationData();
}

其中 PaginationData 是定义的接口

public interface PaginationData<T> {

    List<T> getPaginatedObjectsList();
}

sendRequest 方法看起来像这样

private <T> T sendRequest(String url, Class<T> clazz) {
   HttpResponse httpResponse = httpClient.send(url);
   
   //Jackson's object mapper to transform the result
   // but this result can be also other type than the PaginatedResponse
   
        try {
            return objectMapper.readValue(httpResponse.getEntity(), clazz);
        } catch (IOException e) {
            throw new ParsingException(e);
        }
   
}

一切正常我只是在调用listOfObjects变量上的 .addAll() 方法时收到警告。此警告指出:未经检查的分配,java.util.List 到 java.util.Collection<? 扩展 T> 原因, paginatedResponse.getPaginationData() 具有原始类型,因此 getPaginatedObjectList() 的结果被删除。

所以问题是当我只是返回包含在列表中的通用对象并且我从通用分页响应中获取它们时如何摆脱警告,该响应可以是实现 PaginatedResponse 的任何类型。

标签: javalistgenericscollections

解决方案


在你的interface PaginatedResponse,PaginationData是原始类型。您应该将其更正为:

public interface PaginatedResponse<T> { // type parameter is required here or at the least at method level getPaginationData()
    Pagination getPagination();
    PaginationData<T> getPaginationData(); // this will remove raw type usage
}

然后,更新paginate(...)方法如下(删除原始类型使用的参数)PaginatedResponse paginatedResponsePaginatedResponse<T> paginatedResponse

private <T> List<T> paginate(int pageNumber, int pageSize, int totalAvailable, PaginatedResponse<T> paginatedResponse, String url) {
  // ...
}

此外,初始化列表List<T> listOfObjects = new ArrayList<>();而不是List<T> listOfObjects = new ArrayList();删除原始类型的使用。


编辑有关方法的后续问题sendRequest()

请使用TypeReferencefrom jackson 而不是ClassforsendRequest()方法。请查看主题“类型擦除”以获取更多详细信息。

像这样定义方法:

private <T> T sendRequest(String url, TypeReference<T> typeReference) {
    // ... your original code ...
    return objectMapper.readValue(httpResponse.getEntity(), typeReference);
    // ... your original code ...
}

像这样称呼它:

    paginatedResponse = sendRequest(url + "?pageNumber=" + pageNumber, new TypeReference<PaginatedResponse<T>>() {});

推荐阅读