Raw use of parameterized class 'Future'

时间:2022-07-23
本文章向大家介绍Raw use of parameterized class 'Future',主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

最近在编码过程中发现一个警告。代码如下:

List<Future> futureList = new ArrayList<>(2);

警告:Raw use of parameterized class 'Future' Inspection info: Reports any uses of parameterized classes where the type parameters are omitted. Such raw uses of parameterized types are valid in Java, but defeat the purpose of using type parameters, and may mask bugs. This inspection mirrors the rawtypes warning of javac.

翻译如下:参数化类型“Future”的原始使用。检查信息:指出省略了类型的参数化类的使用。这种对参数化类型的原始使用在Java中是有效的,但是会破坏使用类型参数的目的,并可能掩盖错误。此检查反映了编译阶段对原始类型的警告。

解析:List<Future>:参数化类型,表示元素类型为Future的列表;List:是与参数化类型相对应的原生态类型;原生态类型List和Java平台没有泛型之前的接口类型完全一样;List<E>:泛型;E:形式类型参数;

那为什么不建议使用原生态类型呢?

答:使用原生态类型会丢失泛型在安全性和表述性方面掉的所有优势。

举个例子:

List list = new ArrayList();
list.add("123");
list.add(1L);
list.add(0.11d);
for (Object o : list) {
    double a = (double) o;
}

这段代码就是直接使用原生态类型的实现,在编译时期不会有任何问题,但是一旦运行就会报错:Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double,代码设计应该使错误尽早被发现,而这就是不安全的表现了,而且可读性而言,缺少了形式类型参数,我们很难明白List存储的类型是什么,表述性变差;

例外

  1. 类文字中必须使用原生态类型,意思是List.class、int.class合法,但是List.class不合法;
  2. 在参数化类型而非无限制通配符类型上使用instanceof的行为是非法的,而使用无限制通配符代替原生态类型,对instanceof不会产生任何影响;
  3. 创建泛型、参数化类型或者类型参数的数组是非法的;

这些例外都源于:泛型信息可以在运行时被擦除;泛型,只存在于代码的编译阶段,并且会在运行时候擦除它们的元素类型信息。擦除就是使泛型可以与没有使用泛型的代码可以随意进行互用;

解决最开始遇到的问题

代码本身没有问题,也使用了参数化类型,但是值得注意的是Future也是一个泛型类。修改如下则不会再有警告:

List<Future<ADXParam>> futureList = new ArrayList<>(2);

但是当我修改后,

这行又报错了,深入进去看到vertx并不规范的源码:

static CompositeFuture join(List<Future> futures) {
    return CompositeFutureImpl.join(futures.toArray(new Future[futures.size()]));
  }

这该如何是好呢? 首先我确定我的使用是安全的,不会在运行时候导致错误,则可通过 @SuppressWarnings("rawtypes")消除使用原生态类型警告。