Java核心编程五:泛型概念

来源:互联网 发布:windows优化大师v7.99 编辑:程序博客网 时间:2024/06/02 23:30
泛型编程和C++的模板比较类似,可以使得我们不用到处使用Object再进行相应的类型转换。由于C类语言都是强类型语言,因此在泛型的实现上必须要有特定的语法,这一点不如动态类型语言方便。

1 泛型的优点
在JDK5之前,泛型是由继承来实现的,容器中存放的是Object类型的对象数组。这样的数组一方面不安全,可以加入各种类型的对象。另一方面不方便,在使用时必须进行向下类型的转换。

2 泛型类定义
public class pair<T,V>{    private T first;    private V sencod;    public T getFirst()   {return first;}    public V getSecond()  {return second;}}//pair<int,int> p;


C++采用template关键字来声明泛型类,两种方式有着本质的不同。

3 泛型方法
public class Alg{    public static <T> T Max(T a,T b)    {            }}alg.<int>Max(3,4);//c++: Max<int>(3,4)


如果编译器有足够的信息推理出类型,也可以不指定类型。
C++将类型放在方法名后面,会导致语法分析的歧义。泛型方法可以定义在泛型类也可定义在普通类中。

4 类型限定
有时,我们希望对模板类型进行限定,以保证类型在我们期待的范围内。
public static <T extends Comparable & Serializable> T max(T[] )...

5 泛型与JVM
虚拟机并不知道泛型的存在,所有类都是普通类。这与C++的实例化类是普通类是一样的。
Java定义的泛型类型,会生成相应的原始类型,即删去类型参数的类型名,类型变量则用限定类型(无则用Object)替换,如果被限定为多个类型,则第一个类型生效。在后续调用时,由编译器自动插入相应的类型转换代码。
class Pair{    private Object first;    private Object second;    public Object getFirst() {return first;}}


如果给出了多个限定类型,则使用第一个类型进行替换,如果没有,则用Object替换。

6 约束与局限性
由于类型擦除的存在,引入了下面的一约束和限制。
6.1 不能用类型参数替换基本类型,即不能声明基本类型的泛型,基本类型无法擦除为Object。
6.2 由于VM中无泛型,所以getClass()及instanceof对于一族泛型只返回同一原始类型。也就是说Pair<String>与Pair<integer>类型上是相同的。
6.3 不能抛出泛型类型对象,泛型类不允许扩展Throwable,但在异常声明中可以使用类型变量。
6.4 不能声明参数化类型的数组,即不能T[] arr;这样的数组在插入元素时将失去类型检查的作用。
6.5 不能new 泛型类型,不能有T t = new T();
6.6 不能在静态域或方法中引用类型变量。
6.7 泛型类型被擦除时,构造函数不能产生冲突。

7 泛型与继承
无论T和S是什么关系,关于T和S的泛型类都没有任何关系。
例如tearch继承自person,但不能认为pair<teacher>是pair<person>的子类。但泛型类可以继承,例如ArrayList<Person>可以继承自List<Person>。


8 通配符类型
待续


9 泛型与反射
待续