0

While I was experimenting with Upper Bounded and Lower Bounded wildcards I found the following code snippet.

    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);

I do not understand why

List<? super Integer>

accepts an

ArrayList<Number>

as an argument.

Since Number is the superclass for Integer and not Integer for Number I would expect to see an error.

IonKat
  • 436
  • 6
  • 12
  • 4
    What part don't you understand, specifically? `ArrayList` is a `List`, so no problem there, and `Number` is a superclass of Integer (as is Object), so no problem there, either. You probably want to give https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java a read-over? – Mike 'Pomax' Kamermans Feb 06 '20 at 23:05

3 Answers3

4
List<? super Integer>

means "a List (or an instance of a subclass of List) that it would be acceptable to add an Integer to".

An ArrayList is a subclass of List; and it's entirely reasonable to add an Integer to an ArrayList<Number>, because all elements of the ArrayList have to be Numbers, and Integer is a subclass of Number.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • 4
    Probably worth noting that the `List` part means 'any `List`' too, and `ArrayList implements List`. Just in case there's some additional confusion there. – BeUndead Feb 06 '20 at 23:06
1

You are most probably confusing super with extends. ? super Integer means that the generic type should be a parent for Integer or Integer itself, Number is a super (aka parent) class for Integer so the argument is acceptable.

Islam Hassan
  • 673
  • 1
  • 10
  • 21
0

List<? super Integer> means you can call the method with an argument typed as List of Integer or as a List of any supertype of Integer.

So one alternative is to give it a list of Integers:

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

or you can call it with a list of numbers, like

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

or you can call it with a list of objects, like

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

In all these cases it's ok for numsUpTo to add Integers to the list because Integer is always a valid element type.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276