源代码如下:
NonGen.java 文件内容:
//14.2.3 泛型提升类型安全性的原理
//NonGen is functionally equivalent to Gen but does not use generics
public class NonGen {
Object ob;//ob is now of type Object
//Pass the constructor a reference to an object of type Object
NonGen(Object o){
ob=o;
}
//return type Object
Object getob(){
return ob;
}
//show type of ob
void showType(){
System.out.println("type of ob is:"+ob.getClass().getName());
}
}
NonGenDemo.java 文件内容:
// Demo the non-generic class
public class NonGenDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
NonGen iOb;
//Create NonGen Object and store an Integer in it .Autoboxing still occurs
iOb =new NonGen(88);
//show the type of data used by iOb.
iOb.showType();
//Get the value of iOb.
//this time ,a cast is necessary.
int v=(Integer) iOb.getob();
System.out.println("value:"+v);
System.out.println();
//Create another NonGen object and store a String in it .
NonGen strOb=new NonGen("Non-Generics Test");
//show the type of data used by strOb.
strOb.showType();
//Get the value of strOb.
//Again, notice that a cast is necessary
String str=(String) strOb.getob();
System.out.println("value:"+str);
// This compiles,but is conceptually wrong !
iOb=strOb;
v=(Integer)iOb.getob();//runtime errror
}
}
说明如下:
首先NonGen类使用Object 替换了所有的T,这使得NonGen能够存储任意类型的对象,就像泛型那样,但是这样也使得Java编译器不知道在NonGen中实际存储的数据类型的任何信息,这很糟糕。
原因之一:
首先对于存储的数据,必须显式地进行类型转换才能提取。
其次许多类型不匹配的错误知道运行的时候才会被发现。
上面的程序运行的时候,出错信息如下:
type of ob is:java.lang.Integer
value:88
type of ob is:java.lang.String
Exception in thread "main" value:Non-Generics Test
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at NonGenDemo.main(NonGenDemo.java:26)
在运行的时候,试图将string转换为integer,这在运行时候发生了异常,这个非常糟糕了。
而使用泛型就避免了这样的问题。
本质上:通过泛型可以将运行时错误转换为编译时错误,这是泛型的主要优势。