Without any introduction to generics, I will post my question straight away. Why is this correct:
static<T extends Object> void m1(List<T> list){
//some code
}
And this is not (doesn't compile):
static void m2 (List<T extends Object> list){
//some code
}
Remember that we could use wildcards in the same approach, which would compile just fine:
static void m2 (List<? extends Object> list){
//some code
}
To sum up, why can we use wildcards declaration in parameters, while using type parameter we must declare it before return type?
There are two main points.
First off, as @akuzminykh said in the comments to the question, the ?
wildcard is basically just a way to tell the compiler "I don't know what this is gonna be, just assume it could be anything that derives from this class/interface, kthxbye". It doesn't declare any parameter that you could make use of within the method, no identifier you can call upon, nothing. However, type parameters do exactly that, and if you declare a new one, it's a different story than just "calling" the wildcard which you don't have to declare.
Secondly, think of how you would declare a type parameter for a generic class. Do you think this would be enough?
public class Foo {
public T extends CharSequence getBar() {...}
}
public class Foo {
public <T extends CharSequence> getBar() {...}
}
No, none of these two options would work. In order to use a generic type parameter within a class, you have to declare it along with the type itself, not along with the methods/fields that use them. Like this:
public class Foo<T extends CharSequence> {
public T getBar() {...}
}
And in order to use a generic type parameter within a method, you have to declare it along with the method itself or the type that contains the method, not along with the method parameters that use them.