Effective-Java读书笔记24-消除非受检警告

摘要:Effective-Java 第24条-消除非受检警告

泛型可能警告类型

用泛型编程时,会遇到许多编译器警告:非受检强制转化警告(unchecked cast warnings)、非受检方法调用警告、非受检普通数组创建警告,以及非受检转换警告(unchecked conversion warnings)

非受检强制转化警告

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

警告

1
2
3
4
Venery.java:4: warning: [unchecked] unchecked conversion
found : HashSet, required: Set<Lark>
Set<Lark> exaltation = new HashSet();
^

原因是在在实例化对象的时候没有加入类型信息。这样导致编译器认为是把 HashSet(原生态类型,见23条)强制转化为非原生态类型。所以消除该警告只需要在实例化原生态类型上加入类型信息即可

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

非受检方法调用警告

非受检普通数组创建警告

非受检转换警告

一般强制转化为带有某个模板对象时会报该警告。

强制消除警告

如果无法消除警告,同时可以证明引起警告的代码是类型安全的,(只有在这种情况下才)可以用一个@SuppressWarnings("unchecked")注解来禁止这条警告。

使用的时候需要注意

  1. 应该始终在尽可能小的范围中使用SuppressWarnings注解。
  2. 如果你发现自己在长度不止一行的方法或者构造器中使用SuppressWarnings注解,可以将它移到一个局部变量的声明中。
  3. 每当使用SuppressWarnings("unchecked")注解时,都要添加一条注释,说明为什么这么做是安全的。

下面这个例子能够体现上面的第2和3点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Adding local variable to reduce scope of @SuppressWarnings
public <T> T[] toArray(T[] a) {
if (a.length < size) {
// This cast is correct because the array we're creating
// is of the same type as the one passed in, which is 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;
}