onlyliuxin / coding2017

218 stars 643 forks source link

Java 中在泛型中 extends 与super的区别 #584

Open Locker1995 opened 6 years ago

Locker1995 commented 6 years ago

贴上昨天在虎牙笔试遇到的范题(记得不是很清楚了) 请选出正确的操作 A.List<? extends Object> list = new ArrayList<>(); list.add(new Object()); B.List<? extends Number> list = new ArrayList<>(); list.add(4.0); C.List<? super Number> list = new ArrayList<>();list.add(4.0); D..... 还有一个忘了,题目的主要意思就是考泛型。

链接转自知乎
这个是我个人认为一个很好的帖子去解释这个问题 https://www.zhihu.com/question/20400700

BradyWZH commented 6 years ago

这份来自JDK 8 Collections.copy()源码,给我们提供了一个案例

/**
     * Copies all of the elements from one list into another.  After the
     * operation, the index of each copied element in the destination list
     * will be identical to its index in the source list.  The destination
     * list must be at least as long as the source list.  If it is longer, the
     * remaining elements in the destination list are unaffected. <p>
     *
     * This method runs in linear time.
     *
     * @param  <T> the class of the objects in the lists
     * @param  dest The destination list.
     * @param  src The source list.
     * @throws IndexOutOfBoundsException if the destination list is too small
     *         to contain the entire source List.
     * @throws UnsupportedOperationException if the destination list's
     *         list-iterator does not support the <tt>set</tt> operation.
     */
    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());
            }
        }
    }