JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)的主要内容,如果未能解决你的问题,请参考以下文章

Java基础 -- 泛型之泛型参数

Java泛型之类型擦除

Java重要技术(19)泛型之泛型的使用方法

Java重要技术(24)泛型之使用反射访问参数化类型

Java重要技术(20)泛型之参数化类型的特点

Java重要技术(21)泛型之参数化类型的特点(续)