【问题标题】:Java Unchecked AssignementJava 未经检查的赋值
【发布时间】:2021-01-23 18:48:19
【问题描述】:

我定义了一个函数,它返回实现 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 extends T> 原因,paginatedResponse.getPaginationData() 具有原始类型,因此 getPaginatedObjectList() 的结果被擦除。

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

【问题讨论】:

  • 您在几个地方使用了raw types。从避免这种情况开始。

标签: java list generics collections


【解决方案1】:

在您的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 paginatedResponse 参数更改为PaginatedResponse&lt;T&gt; paginatedResponse 以删除原始类型的使用):

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

此外,将列表初始化为 List&lt;T&gt; listOfObjects = new ArrayList&lt;&gt;(); 而不是 List&lt;T&gt; listOfObjects = new ArrayList(); 以删除原始类型的使用。


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

对于sendRequest() 方法,请使用来自jackson 的TypeReference 而不是Class。请查看主题“类型擦除”了解更多详情。

这样定义方法:

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>>() {});

【讨论】:

  • 感谢@Viral 的评论。不幸的是,它只将警告移至 paginatedResponse = sendRequest(url + "?pageNumber=" + pageNumber);返回 private T sendRequest(url) 的方法
  • @MarkyMark,您的问题中没有关于sendRequest() 方法的参考/详细信息。请相应地更新您的问题。
  • 我已更新问题以显示 sendRequest 方法。请检查
  • @MarkyMark,请查看主题“类型擦除”以获取更多详细信息。在您的情况下,您应该使用来自 jackson 的 TypeReference 而不是 sendRequest() 方法的类。像这样定义:private &lt;T&gt; T sendRequest(String url, TypeReference&lt;T&gt; typeReference),像这样使用它:objectMapper.readValue(httpResponse.getEntity(), typeReference); 并像这样传递它:paginatedResponse = sendRequest(url + "?pageNumber=" + pageNumber, new TypeReference&lt;PaginatedResponse&lt;T&gt;&gt;() {});
  • 我已经更新了这个答案的细节以便更好地理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多