读书人

泛型类型的子类及通配符的施用

发布时间: 2012-08-28 12:37:01 作者: rapoo

泛型类型的子类及通配符的使用

最近碰到一个泛型的问题, 就在网上找技术贴, 挖坟挖出个08年的技术贴, 解决了问题

?

来源: http://webservices.ctocio.com.cn/wsjavtec/128/8571628_1.shtml

?

?

?

?

原文:

  在java语言中,我们通俗讲一个类是另一个类的子类型,是通过使用extends关键字去继承某一个类或者使用implements关键字去实现某些接口。

  我们不妨试想想,若果List< Integer>类型的变量可以成功赋值给List< Number>类型的变量,会出现什么情况?我们可能在程序的某个位置添加一个double类型的元素进去numList中,而实质上在numList中其它元素都是Integer的类型的元素,这样就违背了泛型的初衷了。

  有时,我们确实希望将形如List< Integer>的List对象赋给List< Number>的变量,这时就要使用extends关键字的通配符。

  (2) 使用extends关键字的通配符

  Example2.3

  List< Integer> intList = new ArrayList< Integer>();

  List< ? extends Number> numList = intList();

  …

  numList.add(1.35); //compile error (can’t do that)

  从Example2.3看到numList这个变量,我们可以将类型参数为Number及其Number子类的List赋给它。

  记住一条规则如果你使用了”? extends T”,一般情况下,你不能往该数据结构中put元素,而你可以做的就是get元素。

  如果要往内put元素,就需要使用下面提到的super关键字的通配符。

  (3) 使用super关键字的通配符

  Example2.4

  List< Integer> intList = new ArrayList< Integer();

  List< ? super Integer> numList = intList;

  numList.add(3); //can put integer or null

  在example2.4我们可以看到< ? super Integer>的意思为,我们可以将类型参数为Integer或Integer超类的List赋给numList变量,并且可以put元素到列表中(注意:在该例子中put进的元素只能为Integer或null类型)。

  一条比较通用的规则:如果要往List中put元素则用< ? super T>,如果要从List中get元素则用< ? extends T>,如果既要get又要put则不使用通配符。

?

?

实践下来, 用 < ? super T > 既可以add, 也可以get元素, 就是用不了 for (T t : tlist) 不过可以用 iterator来代替

?

/***  执行环境 Eclipse3.5  JDK1.5 */class A {   protected int a;      public A(int value) { a = value; } public int get(){return a; }}class AA extends A{   public AA(int value) { super(value); }}public static main(String[] argc){   List< ? super A > alist = new ArrayList<A>();    // 以下3种类型,都可以add进list    A a  = new A(1);     alist.add(a);    A a1 = new AA(2);     alist.add(a1);    AA a2 = new AA(3);   alist.add(a2);   Iterator  aa = alist.iterator();   while ( aa.hasnext()){        A  theA = (A)aa.next();       System.out.println(theA.get() );  // 输出1/2/3  }    // 下面代码编译报错    for( A theA : alist) {   }}
?

?

?

读书人网 >其他相关

热点推荐