为什么 "List<? super Integer> myList" 作为方法中的参数可以接受 ArrayList<Number> numberList = new ArrayList<>();

Why "List<? super Integer> myList" as an argument in a method can accept an ArrayList<Number> numberList = new ArrayList<>();

当我尝试使用上界和下界通配符时,我发现了以下代码片段。

    static void numsUpTo(Integer num, List<? super Integer> output) {
    IntStream.rangeClosed(1, num)
            .forEach(output::add);
}

    ArrayList<Integer> integerList = new ArrayList<>();
    ArrayList<Number> numberList = new ArrayList<>();

    numsUpTo(5, integerList);
    numsUpTo(5, numberList);

我不明白为什么

List<? super Integer>

接受

ArrayList<Number>

作为参数。

由于 Number 是 Integer 的超类而不是 Number 的 Integer,所以我希望看到错误。

List<? super Integer>

表示"a List (or an instance of a subclass of List) that it would be acceptable to add an Integer to"。

一个ArrayListList的一个子类;将Integer添加到ArrayList<Number>是完全合理的,因为ArrayList的所有元素都必须是Number,而IntegerNumber.

您很可能将 superextends 混淆了。 ? super Integer 表示泛型类型应该是 Integer 或 Integer 本身的父级,Number 是 Integer 的超级(也称为父级)class,因此参数是可以接受的。

List<? super Integer> 表示您可以使用类型为整数列表或任何超类型整数列表的参数调用该方法。

所以一个替代方法是给它一个整数列表:

ArrayList<Integer> ints = new ArrayList<>();
ints.add(new Integer(0));
numsUpTo(ints);

或者您可以使用数字列表来调用它,例如

List<Number> nums = new ArrayList<>();
nums.add(new Double(1.4));
nums.add(new Integer(3));
numsUpTo(nums);

或者您可以使用对象列表来调用它,例如

List<Object> objects = new LinkedList<>();
objects.add("hello");
objects.add(new Integer(42));
objects.add(new Double(3.14));
numsUpTo(objects);

在所有这些情况下,numsUpTo 都可以将整数添加到列表中,因为整数始终是有效的元素类型。