一文读懂《Effective Java》第24条:合理使用@SuppressWarining消除非受检警告

点击上方蓝字关注我们

使用泛型编程时,会遇到许多编译器警告,例如:非受检强制转换警告(unchecked east warning)、非受检方法调用警告、非受检普通数组创建警告、非受检转换警告(unchecked conversion warnings)。

消除受检警告:修改代码

容易消除的受检警告,举个例子:下面创建一个HashSet对象,但是在声明中没有标志泛型的类型,因此编译器会提醒我们此处缺少泛型的声明。

  Set<Lark> exaltation = new HashSet();

我们可以通过修改代码以消除提示的警告:

Set<Lark> exaltation = new HashSet<Lark>();

不容易消除的受检警告,往往值得是那些需要进行一番思考,比如:业务中抽象出来的代码块或方法,它们已经早已定型并被广泛使用了。那么我们可以用一个 @SuppressWarnings("unchecked") 注解来禁止这条警告。

注意如果不能证实代码是类型安全的,那就只是一个错误的安全感,在编译时虽然可以过关,但运行时仍然可能抛出 ClassCastException 异常。

使用SuppressWarnings注解

SuppressWarnings 注解可以用在任何粒度的级别中(从局部变量到整个类都可以),但我们要坚持一个使用原则:始终在尽可能小的范围中使用 SuppressWarnings 注解,且不要在整个类上使用 SuppressWarnings 注解(会掩盖所有重要的警告)。

下面我们举个例子演示 @SuppressWarnings 的使用:ArrayList 类的 toArray(T[] a) 方法。先看源码:

    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

我们如果编译 ArrayList,上面得到方法会产生一个警告:

SuppressWarnings 注解放在returen 语句时非法的,因为它不是一个生命,最好方法是声明一个局部变量来保存返回值,然后再将 SuppressWarnings 注解“打在”这个局部变量的声明,同时最好要有一条注释来说明为什么是安全的。

于是我们有了以下的改正:

  public static <T> T[] toArray (T[] a) {
    if (a.length < SIZE) {
      // 这个强制转换是正确的,因为创建的数组是和传入的数组类型一致的,使用了泛型参数列表 T[]
      @SuppressWarnings("unchecked")
      T[] result = (T[])Arrays.copyOf(elements, SIZE, a.getClass());
      return result;
    }
    System.arraycopy(elements, 0, a, 0, SIZE);
    if (a.length > SIZE) {
      a[SIZE] = null;
    }
    return a;
  }

总结

总结一下,非受检警告非常重要,开发者一般不要忽略它们。每一条警告都表示可能在运行时抛出 ClassCastException 异常,尽量做到:

  1. 尽最大努力消除受检警告;

  2. 即使不能完全消除,也要尽可能证明引起警告的代码是类型安全的,并可以在尽可能小的范围中,使用 @SuppressWarnings("unchecked") 注解禁止警告;

  3. 同时把禁止该警告的原因记录下。

推荐

Docker 核心设计理念

Kafka 原理总结

一文带你读懂排序算法(二):希尔排序算法

一文读懂《Effective Java》第23条:不要在新代码中使用原生态类型

一文读懂《Effective Java》第20条:类层次优于标签类

一文读懂《Effective Java》第7条:避免使用终结方法

‍‍‍‍‍一文读懂《Effective Java》第6条:消除GC触及不到的过期对象引用‍‍‍‍‍

一文带你读懂Object类源码

一文带你读懂HTTP协议的前世今生

一文带你读懂BigDecimal源码

一文读懂《Java并发编程实战》:第1章 多线程安全性与风险

—END—

扫描二维码

获取技术干货

后台技术汇

点个“在看”表示朕

已阅

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值