• 廖雪峰Java4反射与泛型-3范型-6super通配符


    1.super通配符

    1.1super通配符第一种用法

    泛型的继承关系

    Pair<Integer>不是Pair<Number>的子类,如
    static void set(Pair<Integer> p, Integer first, Integer last){...}
    set()不接受Pair<Number>
    使用<? super Integer>使方法接收所有泛型类型为Integer或Integer超类的Pair类 
    
    package com.testArray;
    
    public class PairHepler {
        static void set(Pair<? super Integer> p,Integer first,Integer last){
            /**
             * 对Pair<? super Integer> 调用setFirst()方法:
             * 方法签名:void setFirst(? super Integer)
             * 可以安全传入Integer类型的变量:p.setFirst(new Integer(123))
             */
            p.setFirst(first);
            p.setLast(last);
        }
        static Integer add(Pair<? extends Number> p){
            /**
             * 对Pair<? super Integer>调用getFirst()方法:
             * 方法签名:? super Integer getFirst()
             * 无法赋值给Integer类型的变量。因为无法确定返回值就是Integer类型,可以确认其是Integer的超类,但无法确认就是Integer
             */
            Number first = p.getFirst();
            Number last = p.getLast();
            return first.intValue()+last.intValue();
        }
    }
    
    <? super Integer>的通配符:
    *    允许调用set方法传入Integer的引用
    *    不允许调用get方法获得Integer的引用
    *    唯一例外:可以获取Object引用:Object o = p.getFirst();
        void process(List<? super Integer> list){...}
    
    class List<T>{
        T.get(int index);//process方法不能调用
        void add(T t);//process方法可以调用
        void remove(T t);//process方法可以调用
    }
    

    1.2super通配符的第二种用法

    <T super Integer>的通配符:
    限定定义Pair<T>时只能是Integer或Integer的超类
    public class Pair<T super Integer>{...}
    Pair<Integer> ip = new Pair<>(1, 2);
    Pair<Number> np = new Pair<>(1, 2);
    Pair<String> sp = new Pair<>("a", "b");//error
    
    

    2.extends和super的区别

    方法参数为<? extends T>和方法参数为<? super T>的区别:
    *    <? extends T>允许调用方法获取T的引用
    *    <? super T>允许调用方法传入T的引用  
    public class Collections{
        //把src的每个元素复制到dest中:List<? super T> dest目标,List<? extends T> src源文件
        public static <T> void copy(List<? super T> dest, List<? extends T> src){
            for(int i=0; i<src.size(); i++){
                T t = src.get(i);
                dest.add(t);
            }
        }
    }
    

    3.无限定通配符

    public class Pair<T> {...}
    public class PairHelper{
        static boolean isNull(Pair<?> p){
            return p.getFirst() == null || p.getLast() == null;
        }
    }
    
    
    <?>的通配符:
    ?号即包括了extends的限制,页包括了super的限制
    不允许调用set方法,null除外
    只能调用get方法获取Object的引用
    因此使用Pair<?>只能获取Object的引用,以及是否为null 
    Pair<?>和 Pair不同,通常情况下可以引入泛型参数<T>消除<?>通配符
    

    Pair.java

    package com.testArray;
    
    public class Pair<T> {
        private T first;
        private T last;
        public Pair(T first,T last){
            this.first = first;
            this.last = last;
        }
        public void setFirst(T first){
            this.first = first;
        }
        public T getFirst() {
            return first;
        }
        public void setLast(T last){
            this.last = last;
        }
        public T getLast(){
            return last;
        }
        public String toString(){
            return "Pair(" + first+", "+last+")";
        }
    }
    

    Main.java

    package com.testArray;
    
    public class Main {
        public static void main(String[] args){
            Pair<Integer> p = new Pair<>(0, 0);
            System.out.println(p);
            set(p, 123, 456);
            System.out.println(p);
            Pair<Number> n = new Pair<>(1.2,3.4);
            System.out.println(n);
            set(n,99,88);
            System.out.println(n);
        }
        static void set(Pair<? super Integer> p, Integer first,Integer last){
            p.setFirst(first);
            p.setLast(last);
            //Integer f = p.getFirst();
        }
    }
    

    4.总结:

    使用类似<? super Integer>通配符作为方法参数时表示:
    *    方法内部可以调用传入Integer引用的方法:obj.setXXX(Integer n)
    *    方法内部无法调用获取Integer引用的方法(Object除外)Integer n = obj.getXxx()
    使用类似<T super Integer>定义泛型类时表示:
    *    泛型类型限定为Integer或Integer的超类
    无限定通配符<?>很少使用,可以用<T>替换
    
  • 相关阅读:
    函数参数太多的一种简化方法
    laravel 获取所有表名
    使用 laravel 的 queue 必须知道的一些事
    git "refusing to merge unrelated histories" 解决方法
    使用 xhprof 进行 php 的性能分析
    php 性能优化
    js原生实现轮播图效果(面向对象编程)
    nextSibling 和nextElementSibling
    如何在页面中使用svg图标
    svg动画 animate
  • 原文地址:https://www.cnblogs.com/csj2018/p/10426465.html
Copyright © 2020-2023  润新知