Reputation: 41
I'm trying to understand why the type erasure of this method doesn't work with wildcards.
public boolean foo(TypeA<TypeB<?>, TypeB<?>> bar) {
return true;
}
// instantiate an object
TypeA<TypeB<TypeC>, TypeB<TypeC>> somethingOtherThanFooBar = ...;
// TypeA<TypeB<?>, TypeB<?>> cannot be applied to TypeA<TypeB<TypeC>, TypeB<TypeC>>
foo(somethingOtherThanFooBar);
I know it will work if the method signature is pulic <T, U> boolean foo(TypeA<TypeB<T>, TypeB<U>> bar)
but this doesn't work with wildcards for a reason I'm failing to understand.
Upvotes: 1
Views: 54
Reputation: 5239
The rule is: A
is-a B
implies G<A>
is-a G<? extends B>
and G<B>
is-a G<? super A>
.
So
TypeC
is-a Object
, thereforeTypeB<TypeC>
is-a TypeB<?>
, thereforeTypeA<TypeB<TypeC>>
is-a TypeA<? extends TypeB<?>>
.There is no type rule that allows you to get from your argument type to your parameter type.
You should check out Scala, which allows you to declare the variance of generic type parameters; if the compiler could know that your generic class would always use the parameter in covariant position, it could allow the conversion you want.
Upvotes: 1