java基础----泛型程序设计

来源:互联网 发布:会员数据分析方法 编辑:程序博客网 时间:2024/06/01 10:23

泛型程序设计

认识泛型;

在以前,ArrayList中维护一个Object数组

publicclassArrayList {

privateObject[]elementData;

...

publicObject get(inti){...}

publicvoidadd(Object o){}

}

ArrayListfiles = new ArrayList();

。。。

Stringfilename = (String)files.get(0);

如果这样,必须要强制转换,如果类型不对,会报类型转换异常


java引进了泛型ArrayList<String>有效的弥补了这个问题


简单的泛型类;


publicclass Pair<T>

publicclass Pair<T,U>

说明:

T为类型变量,泛型类可以有多个类型变量,类定义中的类型变量指方法的返回类型以及域和局部变量的类型。

类型变量使用大写,java库中,使用变量E表示集合的元素类型,KV分别表示表的关键字与值的类型,T(需要时还可以用临近的字母US)表示“任意类型”,


泛型方法;

classArrayAlg{

publicstatic <T> T getMiddle(T...a){

returna[a.length / 2]

}


}

说明:

在泛型方法中<>中的T是指这个方法的返回类型

调用这个方法:

Stringmiddle = ArrayAlg.<String>getMiddle(“john”,”Q”,”Public”)

等同于

Stringmiddle = ArrayAlg.getMiddle(“john”,”Q”,”Public”)

泛型方法可以定义在普通类中,也可以定义在泛型类中。


类型变量的限定;

publicstatic <T extends Comparable> T getMiddle(T[] a){...}

在这个类型变量限制成这个T是实现了这个接口

说明;

多个限定类型用”&”分隔,在限定类型中可以有多个接口,但只能有一个类,并且这个类必须在限定列表的第一个

<Textends ArrayList & comparable & Serializable>




泛型代码与虚拟机;


Java虚拟机是不存在泛型类型对象的,所有的对象都属于普通类。

虚拟机的一种机制:擦除类型参数,并将其替换成特定类型,没有指定特定类型用Object代替,如

classPair<T>变为classPair<Object>

为了保持类型安全性,虚拟机在有必要时插入强制类型转换。

桥方法的合成用来保持多态性。

协变类型允许子类覆盖方法后返回一个更严格的类型。


约束与局限性;

1.不能用基本类型实例化类型参数

Pair<Double>Pair<Integer>,只能用包装类,原因是类型变量为Object

2.运行时类型查询(instanceof)只适用于原始类型

ainstanceof Pair<String>只是查询a是不是Pair类型的

3.不能创建参数化类型数组

Pair<String>[]table = new Pair<String>[10] //error

原因是虚拟机的擦除类型参数机制,解决方法

考虑使用ArrayList<Pair<String>>进行

4.不能实例化类型变量

newT() //error

5.泛型类的静态上下文中的类型变量无效

不能在静态域或者方法中引用类型变量

6.不能抛出或捕获泛型类的实例

Java中,publicclassPair<T>extendsException{...}这种泛型类扩展子Throwable是不合法的,不能通过编译器。也不能再catch子句中使用类型参数

7.注意擦除后的冲突

publicclass Pair<T>{

publicboolea equals(T value){...}

}

从这个类的定义中来看,存在两个equals方法,一个是自身定义的publicboolean equals(T value){...},一个是从Object继承的publicboolean equals(Object obj) {...},但类型擦除以后,前者方法成为了publicboolean equals(Object value){...},而在一个类中同时存在两个方法名和参数一样的方法是不可能的,所以这里引发的冲突是没法通过编译器的。可以通过重新命名方法进行修正。


通配符类型

Pair<?extends Employee>

表示任何泛型Pair类型,它的类型参数是Employee的子类

"?"表示通配符,它的存在必须存在泛型类的类型参数中

通配符的超类型限定

classPair<? super Manager>

直观的讲,带有超类型限定的通配符(super)可以向泛型对象写入(set),带有子类型限定的通配符(extends)可以从泛型对象读取(get)


无限定通配符

无限定通配符去除了超类型和子类型的规则,仅仅用一个"?"表示,并且也只能用于指定泛型类的类型参数中


反射与泛型

Class类是泛型的,String.class实际上是一个Class<String>类的对象







0 0
原创粉丝点击