你的位置:首页 > Java教程

[Java教程]JAVA泛型之? extends T:(通配符上限)和? super T(通配符下限)


  一.通配符上限和通配符下限接受的类型

  通配符上限:<? extends T>

  通配符下限:<? super T>

  以下代码是测试结果,注释为解释说明

 1 package xayd.hjj; 2  3 import java.util.ArrayList; 4 import java.util.List; 5  6 class A{} 7 class B extends A implements F{} 8 class C extends A{} 9 class D extends A{}10 class E{}11 interface F{}12 13 public class Test{14   15   public static void main(String[] args) {    16     17     //下面五行代码说明:List<? extends A>接受A或者继承A的类18     List<? extends A> listA = new ArrayList<A>();19     List<? extends A> listB = new ArrayList<B>();20     List<? extends A> listC = new ArrayList<C>();21     List<? extends A> listD = new ArrayList<D>();22     // List<? extends A> listE = new ArrayList<E>(); //编译不能通过,类E与类A无关23     24     25     //下面三行代码说明:List<? super B>接受B或者的父类26     List<? super B> listA1 = new ArrayList<A>();
       List<? super B> listA2 = new ArrayList<B>();27 List<? super B> listF = new ArrayList<F>();28 //List<? super B> listC1 = new ArrayList<C>(); //编译不能通过,类C不是类B的父类29 30 }31 }

 

   二.通配符下限和通配符上限存取问题

   通配符上限:<? extends A>

   List<? extends A> list = new ArrayList<B>();

   这样定义一个list的时候,是不允许向这个list添加任何东西的。list可以接受其B类型和B的子类。像list中添加对象的时候因为编译器不能确定这个子类的确切类型,因此不允许向里添加任何对象。唯一可以添加的是null。也可以这样理解:Fruit是Apple的父类,也是orange的父类。但是你不能说Fruit就是Apple或者orange。

   代码测试如下:

 1 package xayd.hjj; 2  3 import java.util.ArrayList; 4 import java.util.List; 5 class A{} 6 class B extends A implements F{} 7 class C extends A{} 8 class D extends A{} 9 class E{}10 interface F{}11 public class Test{12   public void a(List<? extends A> list){13     list.add(null);    //编译通过,但无实际意义14     // list.add(new B()); //编译不能通过15     // list.add(new A()); //编译不能通过16     17   }18 19   public static void main(String[] args) {    20     Test test = new Test();21     List<? extends A> listB = new ArrayList<B>();22     test.a(listB);23     24   }25 }

 

  

  通配符下限:<? super B>

  List<? super B> list = new ArrayList<A>();

  这样定义一个list的时候,允许向这个list添加对象。list可以接受其B类型和B的父类。像list中添加对象的时候编译器能确定确切类型。也可以这样理解:Fruit是Apple的父类,也是orange的父类。我们可以说Apple就是一个Fruit。

   代码测试如下:

 1 package xayd.hjj; 2  3 import java.util.ArrayList; 4 import java.util.List; 5 class A{} 6 class B extends A implements F{} 7 class C extends A{} 8 class D extends A{} 9 class E{}10 interface F{}11 public class Test{12   13   public void b(List<? super B> list){14     15     16     list.add(new B());   ////编译通过17     //list.add(new A());  //编译不能通过,要使用类型转换18     list.add((B) new A()); ////编译通过   19     20   } 21   public static void main(String[] args) {        22     List<? super B> listA = new ArrayList<A>();23     test.b(listA);24     25     26   27     28   }29 }