原生类型

Author Avatar
贾康 11月 11, 2016

#原生类型
原生类型是指那些不带类型参数的泛型类或接口。举例来说,对于泛型类Box:

1
2
3
4
public class Box<T> {
public void set(T t) { /* ... */ }
// ...
}

为了创建参数化的Box类,我们需要提供一个类型参数给T,:

1
Box<Integer> intBox=new Box<>();

如果实际的类型参数被隐藏起来,你可以创建一个原生类型的Box

1
Box rawBox = new Box();

因此Box是Box<T>的原生版,然而一个非泛型类或接口不是原生类型。

原生类型一般在遗留代码中出现,因为很多API的类(比如说Collections)在JDK5.0之前不是泛型。我们大体上可以使用之前的特性。比如使用一个Object给Box赋值。为了代码兼容性,将泛型版本的对象赋值给原生版本是可以的。

1
2
Box<String> stringBox = new Box<>();
Box rawBox = stringBox; // OK

但是如果反过来就会有警告出现

1
2
Box rawBox = new Box(); // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox; // warning: unchecked conversion

如果原生类型调用泛型方法一样会产生警告

1
2
3
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8); // warning: unchecked invocation to set(T)

这个警告的出现是因为原生类型没有经过类型的检查,将不安全代码的检查推迟到了软件运行时。因此,我们应该避免使用原生类型。

类型删除部分有更多关于java编译器如何使用原生类型的信息。

###’未检查错误’信息
正如之前所说的那样,当遗留代码和泛型代码混用的时候,你也许会遇到下面这样的警告信息:

1
2
Note: Example.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

当旧的API操作原生类型的时,可能会出现这种情况:

1
2
3
4
5
6
7
8
9
10
public class WarningDemo {
public static void main(String[] args){
Box<Integer> bi;
bi = createBox();
}
static Box createBox(){
return new Box();
}
}

“unchecked”表示编译器没有足够的信息进行类型检查来保证类型的安全。默认情况下这个警告是被禁用的。如果你想看到这个警告,请在编译时加上 -Xlint:unchecked选项。
加上这个选项后重新编译我们的得到如下的编译信息:

1
2
3
4
5
6
WarningDemo.java:4: warning: [unchecked] unchecked conversion
found : Box
required: Box<java.lang.Integer>
bi = createBox();
^
1 warning

为了彻底禁用未检查警告,使用’-Xlint:-unchecked’选项。注解 @SuppressWarnings(“unchecked”)抑制了未检查警告。
下一页