学习日记 --泛型

来源:互联网 发布:微信假红包软件 编辑:程序博客网 时间:2024/06/08 02:43

java泛型的核心--擦除

java泛型解决的问题—类型转换的编译器检查,尤其是在容器中,JDK5之前是用OBject实现泛型,这样任何类型都可以放,但是取的时候强转就报错,很难排查。

---------------------------------------

擦除的级别: 一  编译器级别(即代码层面的T extends   ClassA),代码手动擦除到ClassA ,编译后一切T 被替换成ClassA

                    二  jvm级别,若是代码没有显示的擦除,那么编译后默认擦除到Object。

 

擦除的原因: 泛型是1.5引入的,再次之前都是用Object达到泛型的效果,实现通用代码。于是为了兼容之前的代码和类库,于是就有了擦除提供编译期的检查,运行期的兼容。

 

擦除的缺点: 由于编译时候回类型擦除,所以就无法把T当做类型,从而对T使用反射,如反射的创建对象等。解决方案是在泛型类中声明一个Class引用,使用的时候将实际类型的Class对象传入。

不能用重载,基类劫持接口(既 Interface  I《T》  ,Class A《T1》 implements I ,Class B《T2》 extends A implements I),

 

------------------------------

泛型的声明方式:

类泛型,对象泛型方法,类静态泛型方法。可以声明T   ,也可以T  extends    ,但是不能声明T super

类静态泛型方法使用的泛型若是类声明是未定义在类上的泛型,需要在方法的返回类型之前声明这个泛型标识。

 

泛型的使用方式:

创建一个泛型类的对象时,或者调用一个泛型方法给这个方法传泛型参数时可以传具体的类型,如果不清楚具体的类型也可以使用通配符

? 无界通配符   ,  ? extends ClassB 基类通配符代表 ClassB及其子类,声明了上届。 ? super ClassB 超类通配符代表了ClassB及其父类

这里需要注意的是泛型使用了通配符相当于一个泛型集合,不要和java的继承体系搞混了,例子如下:

Class A {}  

Class B extends A{}   

Class C extends B{}

 

List<? extends  B>  ll1  代表的是ll1这个可以指向很多个泛型的List,但是List持有的泛型类型必须是B和B的子类,   List<C>,List<B> 都是List《? extends B》的子类,由于声明的是上界B,故而ll1.add()是不安全的,因为不知道它的子类到底是什么,就意味着任何类型,而相对于Java来说继承体系越靠上是越安全的,只能add(null),但是get方法是安全的,可以返回类型是安全的上界类型B

 

List<? super B>ll2 同样指向很多泛型,List<A>,List<B>都是它的子类。此时是声明的下限B,于是此时add方法是可以转换成安全的B的,也就是说add方法可用,但是get不知道他的父类到底是哪个,所以不是安全的。

 

 

-------------------------------------

泛型的使用场景:

1 自限定

2 混型

静态代理,动态代理,接口混型,装饰模式

3 潜在类型机制的补偿  

反射,适配器模式

 

0 0
原创粉丝点击