您的位置:首页 > 编程语言 > Java开发

JavaSE基础学习笔记-提高篇-JDK1.5新特性-泛型

2013-11-22 02:24 323 查看
泛型是JDK1.5以后提供的一个重量级新特性,这对于Java来说有着革命性的意义,泛型的出现为Java的安全性又加上了一把大锁,泛型可以用于类,方法,变量,接口,具体的语法规则就不再敖述了,下午简单概括一个泛型类,泛型方法等的特点和使用泛型时的注意事项。

泛型,是提供给javac编译器使用的,目的是在编译期能够尽可能的找出程序可能出现的错误,所以泛型的一大特点就是擦除,即在运行时不会带有任何有关泛型的信息。

1.因为泛型是在JKD1.5才出现而不是在Java诞生的时候就具备泛型特性,所以泛型的一大重要内容就是要向前兼容。

①参数化类型的引用可以指向一个原始类型参数:如 Collection<String> c = new Vector();

②原始类型引用可以指向一个参数化类型的对象:如 Collection c = new Vector<String>();

2.参数化类型不考虑类型参数的继承关系,被用作参数的类型具有唯一性

例如: Vector<String> v1 = new Vector<Object>();

Vector<Object> v2 = new Vector<String>();

这两种定义方法都是错误的,比如第一个示例,引用声明时只能接受String类型的对象,而实际对象声明的是可以接受任何继承自Object的对象,假设你确实绕过了编译器检查而向实际对象中存储了一个Integer对象,那么当用v1去获取对象时,拿到的确是一个Integer,这对于泛型来说是不能容忍的。

3.在创建数组实例时,数组的元素不能使用参数化的类型,例如:

Vector<Integer> [] vi = new Vector<Integer>[];

4.在返乡方法中,在对泛型类型进行参数化的时候类型参数的示例必须是引用

类型学,不能是基本数据类型,例如:

Public void show(T[] t){

}

调用时: obj.show(new int[]{2,4}) 这是不被允许的,当然如果参数列表是 T t,那么可以向方法传入一个基本数据类型,但不是泛型参数接收基数据类型,而是JVM对被传输的基本类型数据进行了装箱操作,使其变成了一个引用数据类型。

*泛型中类型参数的类型推断问题:

编译器判断泛型方法的实际类型参数的过程称之为类型推断,类型推断是相对于直觉推断的,其实现方法是一种非常复杂的过程。

根据调用泛型方法时世界传递的参数类型或返回值类型来推断,具体规则如下:

①当某个类型变量在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时的实际应用类型来确定,即直接柑橘调用方法时传递的参数类型和返回值来确定泛型参数的类型。例如:

Swap(new String[3]),3,4); ----> static <E> void swap(E[],int i,int j){}

当中的E为Integer类型

②当某个类型参数变量在整个参数列表中的所有参数和返回值类型的多次被使用时,如果调用方法时这多处的实际应用类型都对应同一种类型,那么泛型类的类型即为该中类型,例如:

Add(3,5) ------> public <T> void add(T a, T b){}

当中的T为Integer类型

③当某个类型变量在整个参数列表中的所有参数和返回值中被多次应用时,如果调用方法时这多次的实际应用类型对应了不同的类型,且设有返回值时,这时候去多个参数的最大并集作为泛型类的类型。例如:

Fill(new Integer[3],3,5f); ---->public <T> T fill(T[] a,t v1,t v2){}

当中的T为Number类型

⑤参数类型的类型推断有传递性,下面第一种情况推断实际参数类型为Object,编译没有问题,而第二种情况则根据参数化的Vector类实例,将类型变量直接确定为String类型,编译将出现问题。

Copy(Integer[5],new String[5]); ---> <T> void copy(T[]a,T[]b){}

Copy(new Vector<String>(),new Integer[5]); ---> <T> void copy(Collection<T> a, T[]b){}

当第一个参数被传递进来的时候T就确定为String了,所以当第二个参数传递进来时发现是Integer就会发生冲突,此处的T为String是一种隐世的判断。

泛型类:当一个类被实例化时,有时候会要求这个对象只能操作某一个类事务,但又不影响这个类的通用性,这时就要用到泛型类。

例如:JavaEE的Dao类的设计

Public class GenericDAo<T>{

Public T filed;

Public void save(T obj){

}

Public void getById(int id){

}

......

}

当一个对象被创建时规定这个对象只能对一个实体Bean进行操作,保证了数据的一致性。

注意:在对泛型进行参数化的时候,类型参数的实例必须是引用类型,不能是基本数据类型。

另外,当一个变量被声明为泛型时,不能被静态变量和静态方法调用,因为静态成员是被所有参数化的类锁共享的,所以静态成员不应该有类级别的类型参数。

<-------------------------------菜鸟初学,有错误请大家指出---------------------------->
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: