Create a class like
public class Play {
public static void main(String[] args) throws Exception {
outer(Integer.class, inner("abc"));
}
static <C> void outer(Class<C> c, List<? super C> s){
}
static <C> List<C> inner(C c) {
return null;
}
}
and it compiles in Java 8! (Both in Eclipse 4.5 and JDK1.8_25) https://ideone.com/Q9JLHP
In Eclipse, all the bounds are inferred correctly, but how could outer
's capture Supplier<? super Integer>
ever been satisfied by the argument Supplier<String>
??
Edit: clarified this is Java 8-specific and made the example less confusing.
inner("abc")
can, at the compiler's discretion, be interpreted as a Supplier
of any supertype of String
. -- for example,
Supplier<Object> inner = inner("abc");
works just fine, because "abc"
is also an Object
. That's what's happening here: inner
is returning you a Supplier<Object>
.
Inference on inner
requires that C
is a supertype of Integer
and String
.
What is C
exactly? That is a complicated story. Both Integer
and String
are Object
, of course. But both are Serializable
too! and Comparable<?>
too....
In the end, it doesn't matter much; all we need to know is that it is a "least upper bound" of String
and Integer
, in whatever way it is defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With