I can't figure out what's wrong with the following code, specifically, why isn't <A extends ClassA>
equivalent to <? extends ClassA>
<? extends ClassA>
.
Shouldn't bar()
be able to call foo()
?
The compiler says The method foo(...) is not applicable for the arguments (...)
(the exact error is specified in a comment below)
static class ClassA {};
static class ClassB<A extends ClassA> {};
private static <A extends ClassA> Collection<ClassB<A>> foo(Collection<ClassB<A>> as) {
return as;
}
private Collection<ClassB<? extends ClassA>> bar(Collection<ClassB<? extends ClassA>> as) {
// Error:
// The method foo(Collection<ClassB<A>>) is not applicable
// for the arguments (Collection<ClassB<? extends ClassA>>)
return foo(as);
}
Thanks!
I don't know exactly why ... but you need to add a generic type to the second method :)
private <T extends ClassA> Collection<ClassB<T>> bar(Collection<ClassB<T>> as) {
return foo(as);
}
The problem is that you're trying to pass something of type Collection<ClassB<? extends ClassA>>
Collection<ClassB<? extends ClassA>>
into something of type Collection<ClassB<A>>
. They are not compatible.
In order for two generic types to be compatible, their type parameters, if neither is a wildcard, must match exactly . Here, the type parameters are ClassB<? extends ClassA>
ClassB<? extends ClassA>
and ClassB<A>
(for some A
); neither is a wildcard, and they can never be exactly the same -- no matter what A
is, it stands in for a specific type. It is true that ClassB<A>
(whatever A
is) will be a subtype of ClassB<? extends ClassA>
ClassB<? extends ClassA>
; but that is irrelevant -- just like String
is a subtype of Object
but Collection<String>
and Collection<Object>
are not compatible.
If you make foo()
slightly more generic, so that the generic parameter is at the top level:
private static <T extends ClassB<? extends ClassA>> Collection<T> foo(Collection<T> as) {
return as;
}
Then you can use capture to do this:
private Collection<? extends ClassB<? extends ClassA>> bar(Collection<? extends ClassB<? extends ClassA>> as) {
return foo(as);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.