Java培训课程之泛型通配符

  • 只能用于声明变量|形参上,一般是形参类型上,表示可以接收任意
  • 不能用在
    • 1、创建对象,即new 后面
    • 2、声明泛型类、泛型接口,即class和interface
    • 3、声明泛型方法,即返回值类型前面<>中

1、匹配任意类型的通配符

/*

 * ?  通配符,类型不确定

 * 1、用于声明变量|形参上

 * 不能用在

 * 1、创建对象

 * 2、声明泛型类、泛型接口、泛型方法

 */

public class TestGenericWildcard {

     public static void main(String[] args) {

          ArrayList<?> list = new ArrayList();

          list = new ArrayList<String>();

          list = new ArrayList<Integer>();

          list = new ArrayList<Object>();

 

          list = Collections.list(new StringTokenizer(“this is a test”));

          //但是此list不能添加任意类型的对象,除了null

          list.add(null);

//        list.add(“”);//因为?类似于Object,但不等价与Object,所以还是类型不确定,所以除了null可以给任意引用类型之外,其他类型对象都不能随便赋

          Object obj = list.get(0);//可以调用get()方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object

          System.out.println(obj);

 

          test(new ArrayList<Object>());

          test(new ArrayList<String>());

          test(new ArrayList<Integer>());

 

          //编译错误:不能用在创建对象上,右边属于创建集合对象

//        ArrayList<?> list2 = new ArrayList<?>();

     }

     public static void test(ArrayList<?> list){

          list.add(null);

//        list.add(“”);

     }

 

     //编译错误:不能用在泛型方法声明上,返回值类型前面<>不能使用?

//   public static <?> void test(ArrayList<?> list){

//       

//   }

}

//编译错误:不能用在泛型类的声明上

/*class GenericTypeClass<?>{

 

}*/

2、受限泛型:上限、下限

(1)通配符指定上限

上限extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<= ,如

  • ? extends Person
  • ? extends Comparable

满足以下规则

  • List<Fruit> 满足 List<? extends Fruit>
  • List<Apple> 满足 List<? extends Fruit>
  • List<FujiApple> 满足 List<? extends Fruit>
  • List<? extends Apple> 满足 List<? extends Fruit>
  • List<?> 不满足 List<? extends Fruit> 因为List<?> 等价于List<? extends Object>

     public static void main(String[] args) {

          ArrayList<Fruit> list1= new ArrayList<Fruit>();

          test(list1);

          ArrayList<Apple> list2= new ArrayList<Apple>();

          test(list2);

          ArrayList<FujiApple> list3= new ArrayList<FujiApple>();

          test(list3);

 

          ArrayList<? extends Fruit> list= new ArrayList<Fruit>();

          test(list);

 

          ArrayList<? extends Apple> list4= new ArrayList<FujiApple>();

          test(list4);

          ArrayList<? extends Apple> list5= new ArrayList<Apple>();

          test(list5);

 

          //编译错误,因为ArrayList<?>类似于ArrayList<? extends Object>

          //而且list6有可能赋值new ArrayList<String>();

          //而且list6有可能赋值new ArrayList<Object>();

          ArrayList<?> list6 = new ArrayList();

//        test(list6);

     }

 

     public static void test(ArrayList<? extends Fruit> list){

如果使用“? extends  类型”接收泛型对象的时候,则不能设置被泛型指定的内容

     public static void test(ArrayList<? extends Fruit> list){

          /*

           * 通通编译错误

           * 只能接收使用,不能修改

           * 因为不知道list最终传入的到底是什么样的集合

          list.add(new Fruit());

          list.add(new Apple());

          list.add(new Peach());*/

 

          //此处只能是Fruit或以上,不能是Apple等子类,因为可能传入的是ArrayList<Fruit>或ArrayList<Peach>

          for(Fruit f:list){

               System.out.println(f);

          }

 

          //Iterator只能使用Iterator<?>或Iterator<? extends Fruit>

          Iterator<? extends Fruit> iter = list.iterator();

          // Iterator<Fruit> iter = list.iterator();//编译错误,因为泛型不支持多态

     }

(2)通配符指定下限

下限super:使用时指定的类型不能小于操作的类,即>=,如

? super Apple

存在以下规则:

  • ArrayList<Apple> 满足 ArrayList<? super Apple>
  • ArrayList<Fruit> 满足 ArrayList<? super Apple>
  • ArrayList<Object> 满足 ArrayList<? super Apple>
  • ArrayList<? super Apple> 满足 ArrayList<? super Apple>
  • ArrayList<? super Fruit> 满足 ArrayList<? super Apple>
  • ArrayList<?> 不满足 ArrayList<? super Apple>因为List<?> 等价于List<? extends Object>,那么可能ArrayList<String>
  • ArrayList<? super FujiApple> 不满足 ArrayList<? super Apple> 因为可能ArrayList< FujiApple>

     public static void main(String[] args) {

          ArrayList<Apple> list1= new ArrayList<Apple>();

          test(list1);

          ArrayList<Fruit> list2= new ArrayList<Fruit>();

          test(list2);

          ArrayList<Object> list3= new ArrayList<Object>();

          test(list3);

 

          ArrayList<? super Apple> list4= new ArrayList<Apple>();

          test(list4);

          ArrayList<? super Fruit> list5= new ArrayList<Fruit>();

          test(list5);

          ArrayList<? super Fruit> list6= new ArrayList<Object>();

          test(list6);

     //编译错误

     /*   ArrayList<? super FujiApple> list= new ArrayList<FujiApple>();

          test(list);*/

 

//        //编译错误,因为FujiApple是Apple的子类

//        ArrayList<? super Apple> list7= new ArrayList<FujiApple>();

//        test(list7);

 

          //编译错误,因为ArrayList<?>类似于ArrayList<? extends Object>

          //而且list8有可能赋值new ArrayList<String>();

          ArrayList<?> list8 = new ArrayList();

//        test(list8);

     }

 

     public static void test(ArrayList<? super Apple> list){}

如果使用“? super类型”接收泛型对象的时候,则能够添加数据,但是不能添加父对象

      public static void test(ArrayList<? super Apple> list){

            /*

             * 通通编译错误

             * 只能接收本类或子类对象

             * 因为不知道list最终传入的到底是什么样的集合,如果传入的是ArrayList<Apple>,那添加Fruit对象就有问题了*/

            list.add(new FujiApple());

            list.add(new Apple());

//          list.add(new Fruit());

 

            //此处只能是Object,不能是Apple,Fruit,因为可能传入的是ArrayList<Object>

            for(Object a:list){

                  System.out.println(a);

            }

      }

 


上一篇:
下一篇: