Skip to content
Advertisement

Java generics impossible assignment?

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>>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement