`
ncs123
  • 浏览: 99917 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JDK1.5 泛型精简版

    博客分类:
  • J2SE
阅读更多
一.泛型的好处:
  理解Java泛型最简单的方法是把它看成一种便捷语法,节省类型转换的代码


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

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



三.擦除:
  泛型其实只是在编译器中实现的而虚拟机并不认识泛型类项,所以要在虚拟机中将泛型类型进行擦除。也就是说,在编译阶段使用泛型,运行阶段取消泛型,即擦除。
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);//合法
  }
}

  解决办法:
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);//方法二  
 }
}



四.限制泛型中类型参数的范围:
 
<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 通配符
•如果你既想存,又想取,那就别用通配符。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics