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?
Adding
<M extends Number>to the first example doesn't add anything the compiler cares about. Remember you are saying "a type which is a supertype of M" if we are saying "M is a subtype of Number" and "the type is a supertype of M", we aren't actually saying if the type is a subtype of Number.For a better example, have
MbeIntegerand the variable be of typeA<Object>. While obviously that won't work, it satisfies all the requirements of the function correctly.Since there exists no way to fix the function definition, it just lets it pass and assumes the call site will catch the problem.