Java集合中的泛型机制
集合中之所以可以存放不同类型的数据是因为全部当作Object类型处理的,当从集合中取出元素并希望表达该数据最原始的类型时就需要进行强制类型转换,强制类型转换不仅使得代码更加繁琐而且可能导致类型转换异常的发生.
为了避免上述问题的发生,从jdk1.5开始提供泛型机制,也就是在集合名称的右边使用<数据类型>的方式明确规定该集合中可以存放的元素类型,若存放其他类型则会报错,数据类型可以随便写,可以是java自带的也可以是我们创建的,但两边必须保持一致。
如:
List<Integer> l1 = new LinkedList<Integer>();
在实际开发过程中,我们可能用到Java多态的机制,左边放一个Person,那么右边Person的子类都可以,如
List<Person> l1 = new LinkedList<Student>();
List<Person> l1 = new LinkedList<Teacher>();
例:用泛型机机制来声明集合
package com.xxx.xxx
import java.util.LinkedList;
import java.util.List;
import xdl.person.Student;
public class TestListType {
public static void main(String[] args) {
// 使用泛型机制来声明集合
List<Integer> l1 = new LinkedList<Integer>();
// 表示l1这个集合中只支持放Integer类型的
// 向集合中添加元素
l1.add(new Integer(1));
l1.add(new Integer(2));
l1.add(new Integer(3));
//l1.add(new String("four")); // 编译报错
System.out.println(l1); //[1, 2, 3]
// 获取集合中下标为0的元素
Integer it = l1.get(0);
System.out.println("it = " + it); // it = 1
System.out.println("---------------------------");
List<String> l2 = new LinkedList<String>();
// 表示l2这个集合只支持放String类型的
List<Student> l3 = new LinkedList<Student>();
// 表示l3这个集合只支持放Student类型的
}
}
泛型的定义
对于整个Java官方库来说,整个List<E> 只写了一个, 而这个一个接口既能处理上面的Integer、又能处理String类型、又能处理Student类型等等,于是我们把它叫做泛型(即:广泛的类型);
泛型的本质
我们看一下LinkedList源码,我们知道尖括号代表泛型,尖括号里面有个E,其实在这里E就相当于这个类的形式参数,
而当我们创建对象的时候会传一个Integer或String或Person进来,这里的Integer或String或Person就相当于实际参数,把实际参数传过来给这个形式参数接收,所以这里E全部替换成Integer或String或Person,以后在使用E就代表Integer或String或Person,
这里有点类似于方法的调用,只是方法的调用传的是数值,而泛型的调用传的数据类型仅此而已,这是泛型的本质。
泛型的原理
泛型机制的原理就是参数化类型,也就是说使用E作为泛型机制的形式参数负责占位,当真正构造对象时需要使用真实的数据类型作为实参传递给E这个形参,从而类中的E全部变成了实参类型。
如何判断哪些类支持泛型,哪些类不支持泛型,怎么去判断呢?