I wonder why does this piece of code compile successfully?
Source code:
abstract class A<K extends Number>
{
public abstract <M> A<? super M> useMe(A<? super M> k);
}
Compiled successfully
How does it work and why does this compile? M is any type, so why it can be used?. Should it be: <M extends Number>
?
This will not compile:
abstract class A<K extends Number>
{
public abstract <M> A<? super M> useMe(A<M> k);
}
Error message:
type argument M is not within bounds of type variable K where M, K are type variables: M extends Object declared in method useMe(A) K extends Number declared in class A
What is the difference?
<M>
with<M extends Number>
in the later allows it to compile as well. – Fonz<? super M>
always includesobject
which can't satisfy the requirement anyway. – FonzA<M> k
: the bound of types ofM
is actually strictlyObject
in compilie time but as your classA<K extends Number>
is declaredA
can only be parametrized with type with which upper boundNumber
. However, the first compiles, because using? super M
at lease convince the compiler that the type might have a bound other than theObject
and can be found out in runtime. – Jodeejodhpur