According to this entry in the Java Generics FAQ, there are some circumstances where a generic method has no equivalent non-generic method that uses wildcard types. According to that answer,
If a method signature uses multi-level wildcard types then there is always a difference between the generic method signature and the wildcard version of it.
They give the example of a method <T> void print1( List <Box<T>> list), which "requires a list of boxes of the same type." The wildcard version, void print2( List <Box<?>> list), "accepts a heterogenous list of boxes of different types," and thus is not equivalent.
How do you interpret the the differences between the following two method signatures:
<T extends Iterable<?>> void f(Class<T> x) {} void g(Class<? extends Iterable<?>> x) {} Intuitively, it seems like these definitions should be equivalent. However, the call f(ArrayList.class) compiles using the first method, but the call g(ArrayList.class) using the second method results in a compile-time error:
g(java.lang.Class<? extends java.lang.Iterable<?>>) in Test cannot be applied to (java.lang.Class<java.util.ArrayList>) Interestingly, both functions can be called with each others' arguments, because the following compiles:
class Test { <T extends Iterable<?>> void f(Class<T> x) { g(x); } void g(Class<? extends Iterable<?>> x) { f(x); } } Using javap -verbose Test, I can see that f() has the generic signature
<T::Ljava/lang/Iterable<*>;>(Ljava/lang/Class<TT;>;)V; and g() has the generic signature
(Ljava/lang/Class<+Ljava/lang/Iterable<*>;>;)V; What explains this behavior? How should I interpret the differences between these methods' signatures?
Iterablefromgdoes compile for some reason:void g(Class<? extends Iterable> x).