Reputation: 15844
I have a class defined like so:
public class Test {
static <T> List<Class<T>> filter(List<Class<T>> input) {
// code here
}
public static void main(String[] args) {
List<Class<? extends Throwable>> list =
new ArrayList<Class<? extends Throwable>>();
filter(list);
}
}
The filter
method call in main
gives the following compile error:
The method filter(List<Class<T>>) in the type Test is not applicable for the
arguments (List<Class<? extends Throwable>>)
I don't understand why <T>
doesn't bind to <? extends Throwable>
. Are there any generics gurus who can help me?
Upvotes: 3
Views: 1667
Reputation: 147164
I believe the problem here is that there is no type for ?
that would do.
Consider if we, for simplicity, replaced Class
with AtomicReference
.
static <T> void filter(List<AtomicReference<T>> input) {
T value = input.get(0).get();
input.get(1).set(value);
}
If the input
consisted of an AtomicReference<Integer>
and an AtomicReference<String>
we would be in trouble.
The underlying problem that pointers to pointers in the presence of polymorphism is difficult. Without generics we can just hand wave. With generics we need to actually mean something.
Upvotes: 4
Reputation: 361
you can also write main as below :
public static void main(String[] args) {
List<Class<Throwable>> list =
new ArrayList<Class<Throwable>>();
filter(list);
}
Upvotes: 0
Reputation: 403581
Ah, the joys of generic signatures.
You can fix it by declaring the parameter as:
static <T> List<Class<T>> filter(List<Class<? extends T>> input) {
// code here
}
As to exactly why, I'm not sure. Too many compilation problems with generics are fixed by trying various things until the red line goes away. Not satisfying.
Upvotes: 4