谬误13 不知其二——泛型在不被指定的情况下是不确定的类型
为了使集合的功能更强大,也为了提高它们的效率和可用性,在Java 1.5及以后的版本中引入了泛型。泛型简言之就是将类型参数化,以达到以代码复用为目的的一种数据类型。它参数化类型,使类型抽象化,从而使其对外表现出更加灵活的功能。泛型的种类很广泛,包括泛型接口、泛型类、泛型方法、泛型事件和泛型委托等。泛型的语法和概念非常类似于C++中的模板,都是为了方便设计一些更加通用的类型,而在Java中,泛型还有另外一个重要作用,那就是避免容器操作中的装箱和拆箱动作。
说明
JDK 1.5提供了泛型,增强了Java的类型安全,可以在编译期间对容器内的对象进行类型检查,在运行期不必进行类型的转换。而在JDK 1.5之前,必须在运行期动态地进行容器内对象的检查及转换。
泛型示例代码如下:
/** * 泛型定义类 * @author CHUNBIN * * @param <T> */ public class GenericClass<T> { T tt; //构造器 public GenericClass (T t){ tt = t; } //覆盖或重写toString方法 public String toString (){ return tt. toString (); } //main ()方法 public static void main (String[] args){ GenericClass<String> gc = new GenericClass<String>("明日科技"); //实例化泛型类 System.out. println (gc); //输出gc的值 } }
执行上述代码后,程序运行的效果如图4.8所示。
图4.8 传入String类型的实参输出的信息
注意
所有的泛型参数名都以T开头,这是一种习惯性的编码规范。
提示
在程序的main ()方法中为泛型传入了一个String类型的实参,实际上可以传入任意类型的实参,如Integer类型,代码如下所示:
GenericClass<Integer> gc = new GenericClass<Integer>(999); //实例化泛型类
如果程序中替换了上述代码,程序同样可以正常工作,替换上述代码后,程序运行的效果如图4.9所示。
图4.9 传入Integer类型的实参输出的信息
上面代码中声明了一个泛型GenericClass<T>,有些人会认为GenericClass<T>是一个不确定类型,这是对泛型的一种误解,和Java中的众多类型一样,带泛型参数的类型同样是一个确定的类型,在不被指定的情况下,它直接继承自Object 类型,也就是说GenericClass<T>是Object类型。但是,泛型类型还是和普通类型有一定区别的,泛型的类型一般被称为开放式类型,开发式类型不能被实例化,如GenericClass<T>是不能直接被实例化的。在GenericClass类的调用代码中,为开放类型指定了实参,这个时候实际上是重新定义了一个新的封闭类型,如GenericClass<String>,这样就可以直接对其进行实例化了。