zoukankan      html  css  js  c++  java
  • Java基础 -- 泛型之泛型参数

    泛型机制常用的参数有3个:

    “?”代表任意类型。如果只指定了<?>,而没有extends,则默认是允许任意类。
    extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类。
    super关键字声明了类型的下界,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object
    前提
    Fruit是Apple和Orange的超类。
    本章通过java代码逐一分析泛型参数的意义和区别
    extends参数:
    [java]  
    public void extend(List<? extends Fruit> list, Fruit fruit){    
            Fruit now = list.get(0);    
            System.out.println("now==>" + now);  
        //    Apple a = list.get(0);  无法通过编译  
            Object o = list.get(0);   
            System.out.println(o);  
            // list.add(fruit); //这句话无法编译      
            // list.add(new Object());  // 无法通过编译  
            list.add(null);//这句可以编译,因为null没有类型信息    
        }   
    在上面的例子中,可以明确从list中取得的记录一定是Fruit,但是无法确定是Apple,list除了传入null外,不能添加其他任何参数;分析原因前先看以下的例子:
    [java] 
    public void testExtendType(){  
        List<? extends Fruit> list = new ArrayList<Fruit>();  
        List<? extends Fruit> list2 = new ArrayList<Apple>();  
        List<? extends Fruit> list3 = new ArrayList<Orange>();  
        extend(list2, new Apple());  
    }  
    从以上代码可以看出:
    extends关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类,List<? extends Fruit> 可以指向 ArrayList<Fruit>()、ArrayList<Apple>()、 ArrayList<Orange>()等。现在如果传入的参数list为new ArrayList<Apple>(),则此时你向此list中添加
    Fruit,则肯定报错。而读取数据时,不管list是什么类型,读取的数据肯定都是Fruit,同时Fruit也是Object。
    通过以上的分析,知道直接往继承extends中的列表中添加记录是不行的,那么如何向extends修饰的list中添加记录,可以使用泛型方法来达到目的:
    [java]  
    public <T extends Fruit> void extendType2(List<T> list, T date){    
            list.add(date);    
        }   
    调用示例如下:
    [java]  
    public void testExtendType2(){    
            List<Apple> list = new ArrayList<Apple>();    
            extendType2(list,new Apple());    
        }  
    super参数
    super用的不多,只简单介绍一下。
    [java]  
    public void superType(List<? super Apple> list, Apple apple){    
            Object o = list.get(0);  
            System.out.println(o);  
        //  Apple a = list.get(0); // 不能编译  
              
         // Apple apple = list.get(0); // 不能编译    
            list.add(apple);  
    //      list.add( new Object());  // 不能编译  
    //      list.add( new Fruit());  // 不能编译  
        }    
    在以上代码中,从list中读取的记录无法确定是任何类型(除Object),list除了添加Apple外,不能添加任何类型的对象(包括Object)。分析原因前先看以下代码:
    [java]  
    public void testSuperType(){    
        List<? super Apple> list = new ArrayList<Apple>();    
        List<? super Apple> list2 = new ArrayList<Fruit>();   
        superType(list2, new Apple());    
    }  
    super关键字声明了类型的下界,表示参数化的类型是所指定的类型,或者是此类型的父类型,直至Object。List<? super Apple > 可以引用  List<Apple>,也可以引用 List<Fruit>,所以无法保证list中都是Apple,但是可以保证,所有list引用的都是Apple的父类,所有向此列表中添 加Apple是没有问题的,而很显然你向List<Fruit>、List<Apple>中添加Object、Fruit对象, 肯定失败,只能够添加Apple。
    ?参数
    “?”代表任意类型。?可以看做 ? extends Object 的缩写。
    [java] 
    public void wideCardType(List<?> list, Fruit fruit ){  
        Object o = list.get(0);  
        System.out.println(list.get(0));  
        //  list.add(fruit);  // 不能编译  
        //  list.add(new Object()); // 不能被编译  
    }  
    [java]  
    public void testWideCardType(){  
            /** 
             * ? 可以看做 ? extends Object 的简化版 
             */  
            List<?> list = new ArrayList<Fruit>();  
            List<?> list2 = new ArrayList<Apple>();  
            List<?> list3 = new ArrayList<Object>();  
              
            wideCardType(list,new Fruit());  
        }  
    List<? super Object> 可以引用  List<任何类型>,而Object是所有的对象的祖先,此list只能添加Object类型对象。
    extends和super意义记忆的技巧
    ? extends A: ?继承A,?是A的子类,或者?是A本身
    ? super B:    ?是B的父类,或者?是B本身
  • 相关阅读:
    OpenGL 五
    OpenGL 四
    对UICollectionView的学习
    KVO的简单用法
    css在各浏览器中的兼容问题
    iOS学习笔记---网络请求
    UI学习笔记---第十六天XML JSON解析
    ui学习笔记---第十五天数据库
    UI学习笔记---第十四天数据持久化
    UI学习笔记---第十三天可视化设计 XIB, StoryBoard
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/5631646.html
Copyright © 2011-2022 走看看