1

I want to know what will be the type parameter that the compiler infers when creating a List and its parameterized type is bounded with extends or super clauses.

List<? extends Number> numbersList = new ArrayList<>(); List<? super Integer> integersList = new ArrayList<>();

rgettman
  • 176,041
  • 30
  • 275
  • 357

2 Answers2

0

It infers whatever the type on the left side is.

List is equivalent too List<Object> so it'll infer to ArrayList<Object>.

Map<String, OutputStream> map = new HashMap<>(); would infer to <String, OutputStream>

EDIT: You updated your question, but it still holds true, the left side will equal the right side, since it has to in order to set them equal

Matthew Kerian
  • 812
  • 5
  • 18
  • But I have tried to write this: `List extends Number> numbersList = new ArrayList extends Number>();` and this gave me an error because parameterized types can't be instantiated โ€“ Omar Mohamed Khallaf Jun 18 '19 at 17:55
  • You cannot use wildcards when creating concrete implementations. โ€“ Turing85 Jun 18 '19 at 17:56
  • @OmarMohamedKhallaf Ah I see what you mean, wild cards are taken out. So extends Foo> goes to Foo, whereas super Foo> will be able to take any object at runtime โ€“ Matthew Kerian Jun 18 '19 at 17:58
0

This is discussed in detail in ยง18 of the JLS.

In your case, List<? extends Number> will be replaced with List<Number> since Number is the upper bound, whereas List<? super Number> will be replaces with List<Object> since Object is the upper bound. You can verify this by a quick test, I coded one up over on Ideone

For a discussion why this is useful, you may take a look at the PECS mnemonic

Turing85
  • 18,217
  • 7
  • 33
  • 58