abstract class Type<K extends Number> {
abstract <K> void use1(Type<K> k); // Compiler error (Type parameter K is not within its bounds)
abstract <K> void use2(Type<? extends K> k); // fine
abstract <K> void use3(Type<? super K> k); // fine
}
The method generic type K shadows the class generic type K, so <K> doesn’t match <K extends Number> in use1().The compiler doesn’t know anything usefull about new generic type <K> in use2() and use3() but it is still legal to compile . Why <? extends K> (or <? super K>) match <K extends Number>?
First of all, let’s rewrite it to avoid shadowing:
In the first method
Kacts as a type parameter ofType<N extends Number>, thus its value sould comply to the bound ofType‘sN. However, method declaration doesn’t have any restrictions on value ofK, therefore it’s not legal. It would be legal if you add a necessary restriction onK:In the following methods, the actual type parameter of
Typeis unknown (?), andKimposes additional bound on it, so that there is nothing illegal in these declarations.Here is a more practical example with the similar declarations: