* jdk1.5的新特性,在没有泛型之前,程序可能存在安全隐患,如:在集合中取出元素时在强制类型转换过程中可能会发全ClassCastException,有了泛型之后就可以避免了这种情况的发生(不用强转),泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、 接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。在java中泛型是给提供给javac编译器使用的,可以限定集合的输入类型,在编译阶段挡住源程序的非法输入,编译器编译包含类型信息的类时给去掉"类型"信息,这一技术 叫做泛型的擦除,即生成的字节码是没有类型信息的,参数化类型和原始类型共享一份字节码。* 泛型:
* -->既然泛型是提供给javac编译器使用的,那么只要穿过编译器,就可以不受泛型 的约束可以添加任意类型的数据。
* Vector称为原始类型。
* Vector<T>中的T称为类型变量或类型参数。
* Vector<String>称为参数化类型。
* Vector<String>中的String称为类型变量的实例或实际类型参数。
Vector<Integer> v1 =new Vector<Integer>();
Vector v2 =new Vector();
System.out.println(v1.getClass() == v2.getClass());//true
// v1.add("abc");穿过编译器用反射来玩。
Vector.class.getMethod("add", Object.class).invoke(v1, "abc");
System.out.println(v1.get(0));
* 参数化类型与原始类型的兼容性。
* 1.参数化类型可以引用一个原始类型的对象:
* Vector<String> v1=new Vector();要是不可以以前写的代码就废了。
* 2.原始类型可以引用一个参数化类型的对象:
* Vector v2 =new Vector<String>();原来的方法接受一个集合参数,新的类型也要能够传进去。
*
* 参数化类型不考虑类型参数的继承关系:
* Vector<Object> v3=new Vector<String>();错,
* Vector<String> v4=new Vector<Object>();错,
*
* 编译器不允许创建泛型变量的数组,即在创建数组实体时,数组的元素不能使用参数化的类型。
* Vector<String>[] v5=new Vector<String>[3];
*
*
* 泛型中的通配符?
* 使用通配符?可以引用其它各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不可以调用与参数有关的方法.
*
* 泛型通配符的扩展:
* 上边界:<? extends T>:T的子类或T本身。
* 下边界:<? super T>:T的父类或T本身。
private static void printCollection(Collection<?> collections)
{
// collections.add("abc");不能调用与类型参数有关的方法,因为它不知道自己未来匹配是什么类型。
for(Object collection: collections){
System.out.println(collection);
}
}
定义泛型方法:
java语言的泛型类似于C++的模板,但限于表面,java的泛型几乎都是编译器中实现的,没有C++的强大。
private static int add(int x,int y){
return x+y;
}
//声明<T>这种类型,T只能是引用数据类型。
private static <T> T add(T x,T y){
return null;
}
定义泛型类型:
如果类的实例对象的多处都要用到同一个泛型参数,即这些地方引用的泛型要保持同一个实际类型。可以定义在类上的泛型。
//定义格式
class DAO<E>{
public void add(E e )
{
}
public E findById(int id)
{
}
//编译不通过,静态不能使用泛型类型
public static E findById2(int id)
{
}
//要想定义泛型,必须自己玩
public static <E> E findById3(int id){}
}
编译器判断泛型方法的实际类型参数的过程 ,称为类型推断。这一过程非常复杂。
swap(new String[3],3,4) à static<E> void swap(E[] a, int i, int j)
add(3,5) à static <T> T add(T a, T b)
fill(new Integer[3],3.5f) à static <T> void fill(T[] a, T v)
int x=(3,3.5f) à static <T> T add(T a, T b)
copy(new Integer[5],new String[5]) à static<T> void copy(T[] a,T[] b);
copy(new Vector<String>(), newInteger[5]) àstatic <T> voidcopy(Collection<T> a , T[] b);