Java开发之道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

谬误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>,这样就可以直接对其进行实例化了。