通过实例比较泛型通配符(T E与?)的用法

static class Point<T>{
        private T x;
        public Point (T x){
            this.x=x;
        }
        public void setX(T x){
            this.x=x;
        }
        public T getX(){
            return this.x;
        }
    }

    /**
     * wild capture在通配符被绑定为新值的时候会警告
     * 因此通配符可防止数据修改,保证数据安全
     */
    public static void fun(Point<?> a){
        // a.setX("AA"); // 编译错误 提示“capture of ?”
        System.out.println(a.getX());
    }
    /**
     * 泛型的意义:
     *      0.待定数据类型提高API灵活性(flexible)
     *      1.使用时指定类型省略了Object类型转换(cast),保证类型安全
     *      2.通过多个继承限制实现类型限制(bound)
     *      3.结合通配符保证数据安全
     * 类型参数:类型待定(由使用者决定)的参数的类型占位符
     * 泛型方法声明方式:【方法修饰符后设置类型参数符号T,形参处使用类型参数符号T】
     * 使用时按照【PECS - producer extends consumer super】
     */
    public static <T extends Father> void testGeneric(List<? super T> fathers, T person) {
        /**
         * 实例化时必须指定类型
         */
        List<? super T> lowList1 = new ArrayList<T>();
        // List<? super T> list1 = new ArrayList<?>(); // 编译出错
        lowList1.add(person);
        // lowList1.add(new Father("father")); // 编译出错
        // list1.add(new Child("00")); // 编译出错,泛型不可传递?
        /**
         * 内部变量(类的成员变量或方法的局部变量)仅可使用已声明的泛型或通配符泛型
         */
        List<T> tmpList = new ArrayList<T>();
        // List<E> tmpList2 = new ArrayList<T>(); // 编译出错,E是未知类型

        /**
         * 可变类型提供灵活性,结合通配符还能保证数据安全
         */
        Point<String> a= new Point<>("A");
        fun(a);
        Point<Integer> b= new Point<>(10);
        fun(b);

        /**
         * 通配泛型因其通配区间内类型无法确定,故通配区间内的方法不可用
         * 上界通配,通配区间为[upLimit, allSubClasses] 有上限无下限 不可添加元素,可用上界及以上层次的方法
         */
        ArrayList<? extends Father> uplist = new ArrayList<Father>();
        // uplist.add(new Object());// 编译出错
        // uplist.add(new Father("father"));// 编译出错
        // uplist.add(new Child("child"));// 编译出错
        if (uplist.size() > 0) {
            Father father = uplist.get(0);
            father.say();
            GrandFather grandFather = uplist.get(1);
            grandFather.say();
            uplist.forEach(var -> var.say());
        }
        /**
         * 下界通配,通配区间为[allParentClasses, lowLimit] 有下限无上限 可添加子类对象元素,仅可用Object公共方法
         */
        ArrayList<? super Child> lowList = new ArrayList<Father>();
        lowList.add(new Child("child"));
        lowList.add(new GrandChild("grandChild"));
        // lowList.add(new Father("father")); // 编译出错
        Object obj = lowList.get(0);
        // Father fatherObj = lowList.get(0);// 编译出错
        /**
         * 以Number类举例下界限定通配
         */
        List<? super Number> data = new ArrayList<>();
        data.add(10);
        data.add(new BigDecimal(1000));
        data.add(10.07f);
        data.forEach(var ->var.toString());
        // data.add(new Object()); //编译报错
    }

 

posted @ 2021-04-12 13:17  小天儿  阅读(113)  评论(0)    收藏  举报