Every time I think I understand generics better (and can answer without compiling), I get to an example where this theory breaks. Here is a very simple example:
static void consumer(List<? super List<String>> param) { System.out.println(param); }
And two invocations:
public static void main(String[] args) { List<String> list = List.of("123"); consumer(list); consumer(List.of("123")); }
To me, none of the invocations should compile. A String
is not a supertype of List
. Still, the second one compiles. But let’s suppose that this happens because the compiler could infer some type here. Of course such a type does not exist and it will fail at runtime, right? Right? Nope. It just works. As such, can someone bring some sanity to my life please?
Advertisement
Answer
Ah darn!
javac --debug=verboseResolution=all Sandbox.java
shows that consumer(List.of("123"))
is compiled to:
instantiated signature: (Object)List<Object> target-type: List<? super List<String>>