首页 > 解决方案 > 在Java源代码中,为什么 ArrayList.add 有参数作为泛型类型 T 而 addAll 有参数作为泛型类型

问题描述

这是Java的源代码ArrayList(使用java 1.8)

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    System.arraycopy(a, 0, elementData, size, numNew);
    size += numNew;
    return numNew != 0;
}

我不太清楚为什么我们只能使用Eforadd()而我们可以使用<? extends E>foraddAll()

标签: javagenerics

解决方案


因为如果你有一个ArrayList<Number>你可以addaInteger和 aNumber和 aDouble因为它们都是E/的子类型,Number但你不能addAlla ArrayList<Integer>if 签名是addAll(Collection<E> c)因为 anArrayList<Integer>不是 (subtype of)ArrayList<Number>因为在 Java 中泛型是不变的。只有将其定义为addAll(Collection<? extends E> c)可以添加具有更具体的通用子类型的列表。这基本上意味着“任何具有作为子类型的泛型参数的集合E


推荐阅读