原始类型(raw type)是一个没有任何类型实参的泛型类或泛型接口的名称。例如,给定泛型类Box:
public class Box<T> {
public void set(T t) { /* ... */ }
// ...
}
要创建Box
Box<Integer> intBox = new Box<>();
如果省略实际类型参数,则创建Box
Box rawBox = new Box();
因此,Box是泛型类型Box
原始类型显示在旧版代码中,因为在JDK 5.0之前,许多API类(例如Collections类)不是泛型的。使用原始类型时,您实际上会获得泛型行为-Box为您提供Object。为了向后兼容,允许将参数化类型分配给其原始类型:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox; // OK
但是,如果将原始类型分配给参数化类型,则会收到警告:
Box rawBox = new Box(); // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox; // warning: unchecked conversion
如果您使用原始类型来调用在相应的泛型类型中定义的泛型方法,也会收到警告:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8); // warning: unchecked invocation to set(T)
该警告表明原始类型会绕过泛型类型检查,从而将不安全代码的捕获推迟到运行时。因此,应避免使用原始类型。
类型擦除部分有对Java编译器如何使用原始类型的详细信息。
(个人注解:区别基本**类型(primitive types)和原始类型(raw types)**两者的概念和含义。基本类型是字面量,不含对象概念;原始类型属于对象。原始类型与其泛型之间的关系,类似于基本类型与其包装类的关系。原始类型会绕过泛型类型检查,应避免使用原始类型,要使用泛型代替)
未检查的错误消息
如前所述,将旧代码与泛型代码混合时,您可能会遇到类似于以下内容的警告消息:
Note: Example.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
当使用原始类型对较旧的API进行操作的时,可能会发生这种情况,如以下示例所示:
public class WarningDemo {
public static void main(String[] args){
Box<Integer> bi;
bi = createBox();
}
static Box createBox(){
return new Box();
}
}
术语“unchecked”表示编译器没有足够的类型信息来确保执行类型安全所需的所有类型检查。尽管编译器会给出提示,但默认情况下禁用“unchecked”警告。要查看所有“unchecked”的警告,请使用-Xlint:unchecked重新编译。
使用-Xlint:unchecked重新编译前面的示例将显示以下附加信息:
WarningDemo.java:4: warning: [unchecked] unchecked conversion
found : Box
required: Box<java.lang.Integer>
bi = createBox();
^
1 warning
要完全禁用unchecked的警告,使用-Xlint:unchecked标志。@SuppressWarnings( “unchecked”)注解禁止unchecked警告。如果您不熟悉@SuppressWarnings
语法,请参阅 注解。