美文网首页
Java中的通配符extends和super

Java中的通配符extends和super

作者: 北雁南飞_8854 | 来源:发表于2018-09-23 21:53 被阅读0次

Java中的通配符extends和super

extends

// Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Number>();
// Integer extends Number
List<? extends Number> foo3 = new ArrayList<Integer>();
// Double extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); 
  1. 读操作(Reading)

    给定以上的赋值语句,可以从foo3中读取什么类型的元素呢?

    Number:Yes,因为foo3中的任何元素都可以保证是Number或Number的子类;

    Integer: No,因为foo3有可能指向List<Double>;

    Number: No,因为foo3有可能指向List<Integer>;

  2. 写操作(Wrting)

    给定以上的赋值语句,可以向foo3中添加什么类型的元素呢?

    Integer: No,因为foo3有可能指向List<Double>;

    Number: No, 因为foo3有可能指向List<Integer>;

    PECS(Producer Extends, Consumer Super)

    如果你需要一个List作为Producer(希望从该List中读取T类型的元素),则需要声明该List为List<? extends T>,这时只能进行get操作,无法向List中add任何类型的元素;

    如果你需要一个List作为Consumer(希望向该List中插入T类型的元素),则需要声明该List为List<? super T>,这时无法保证get到的元素的原有类型,只能得出是Object或Object的子类,只能add T或T的子类元素。

    如果你即需要get、也需要add操作,则不能使用通配符,必须精确声明为List<T>。
    举例:
    jdk中Collections类的copy()方法:

    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
            int srcSize = src.size();
            if (srcSize > dest.size())
                throw new IndexOutOfBoundsException("Source does not fit in dest");
    
            if (srcSize < COPY_THRESHOLD ||
                (src instanceof RandomAccess && dest instanceof RandomAccess)) {
                for (int i = 0; i < srcSize; i++)
                    dest.set(i, src.get(i));
            } else {
                ListIterator<? super T> di = dest.listIterator();
                ListIterator<? extends T> si = src.listIterator();
                for (int i = 0; i < srcSize; i++) {
                    di.next();
                    di.set(si.next());
                }
            }
        }
    

相关文章

网友评论

      本文标题:Java中的通配符extends和super

      本文链接:https://www.haomeiwen.com/subject/efwqoftx.html