JDK1.5 泛型精简版

[size=large]一.泛型的好处:[/size]
理解Java泛型最简单的方法是把它看成一种便捷语法,节省类型转换的代码


[size=large]二.协变:[/size]
在数组中协变是支持的,Apple[]可以复制给Fruit[].但是在泛型中是不支持协变的,List<Apple>是不能复制给List<Fruit>,例如:
take(List<Fruit> fruits){}//只有真正的List<Fruit>才能调用take(..),Fruit的子类是无法调用的

[color=red]解决办法:[/color]
take(List<? extends Fruit> fruits){
fruits.add(new Apple());//编译出错,只能进行读,不能进行写操作,因为List内的具体类型是不确定的
}//Fruit的子类是都可以调用



[size=large]三.擦除:[/size]
泛型其实只是在编译器中实现的而虚拟机并不认识泛型类项,所以要在虚拟机中将泛型类型进行擦除。也就是说,在编译阶段使用泛型,运行阶段取消泛型,即擦除。
List<Integer>,List<String>

1.在java中编译器只生成唯一的一份目标代码List类,该泛型类的所有实例都映射到这份目标代码上,在需要的时候执行类型检查和类型转换。
2.在实例化一个泛型类或泛型方法时都产生一份新的目标代码,针对Integer,String类型的两个List类

擦除带来的问题:
public class Erased<T>{
private T[] arr;
public Erased(){
T t = new T();//illegal因为在编译的时候不知道构造哪个具体的类
arr = new T[1];//illegal
arr = (T[])new Object[1];//Unchecked warning
}

public void doSomething(Set<?> set){
Set<?> copy = new HashSet<?>(set);//illegal
Set<?> copy2 = new HashSet<Object>(set);//合法
}
}

[color=darkred]解决办法:[/color]
public class Erased<T>{
private T[] arr;
private Class<T> type;

public Erased(Class<T> type){
this.type = type;
Class<T>[] arrs = new Class[1];//方法一
arr = (T[])arrs;
//arr = (T[])Array.newInstance(type,1);//方法二
}
}



[size=large]四.限制泛型中类型参数的范围:[/size]
<K extends String>和<V super Integer>
不是表示继承和超类,而是表示类型的范围,表示K<=Sting,V>=Integer
class C<T extends Comparable<? super T> & Serializable>
我们来分析以下这句,T extends Comparable这个是对上限的限制,Comparable<? super T>这个是下限的限制,Serializable是第2个上限。一个指定的类型参数可以具有一个或多个上限。具有多重限制的类型参数可以用于访问它的每个限制的方法和域。

总结 ? extends 和 the ? super 通配符的特征,我们可以得出以下结论:

•如果你想从一个数据类型里获取数据,使用 ? extends 通配符
•如果你想把对象写入一个数据结构里,使用 ? super 通配符
•如果你既想存,又想取,那就别用通配符。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值