非受检警告是什么?
使用泛型进行编程时,编译器会发出许多警告,如:非受检强制装换警告、非受检方法调用警告、非受检普通数组创建警告以及非受检普通转换警告。

为什么要消费非受检警告?
消除了警告就可以确定代码是类型安全的,就意味着不会再出现ClassCastException异常,你会更加自信自己的程序可以实现预期的效果。

有许多非受检警告很容易消除,但也有很难消除。

非受检警告很容易消除例子:

Set<Person> set = new HashSet<>();

编译器会细致地提醒你哪里出错了:

warning:[unchecked] unchecked conversion
found : HashSet, require: Set<Person>

你就可以纠正所显示的错误,消除警告:

Set<Person> set = new HashSet<Person>();

JDK1.7以及以上是不会存在此警告的,因为jdk1.7后会自动类型判断。

非受检警告很难消除例子:

public <T> T[] toArray(T[] a){
        if(a.length < size){
            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;
    }

难以消警告,添加@SuppressWarning(“unchecked”)注解来消除这条警告。

public <T> T[] toArray(T[] a) {
        if (a.length < size) {
            @SuppressWarning("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;
    }

但是添加@SuppressWarning(“unchecked”)注解来消除这条警告之前,你不能证明代码的安全性,那就是给自己的一种错觉。编译器没有了警告,但是运行时可能会出现ClassCastException异常。所以添加@SuppressWarning(“unchecked”)时,一定要证明自己的代码类型是安全的。

SuppressWarnings注解可以用任何粒度的级别中,从单独的局部变量声名到整个类都是可以的。应该始终在尽可能小的范围内使用SuppressWarnings注解。它通常是个变量声名或者是非常简短的方法或者构造器,永远不要在整个类上使用SuppressWarnings注解,这么做很可能会掩盖了重要的警告。

每当使用SuppressWarnings注解的时候,都要添加一条注释,说明为什么这么做是安全的。这样可以帮助其他人理解代码,更重要的是,可以尽量减少其他人修改代码后导致计算不安全的概率。

总之,非受检警告很重要,不要忽略它们。每一条警告都表示可能在运行时抛出ClassCastException异常。要尽最大的努力去消除这些警告。如果无法消除但是可以证明引起警告的代码是安全的,就可以在尽可能小的范围中,使用@SuppressWarnings(“unchecked”)注解来禁止警告,但是要把禁止的原因记录下来。