Sorry if the title seems confusing, but some examples are in order.
Let's say I have some Java class with a generic type parameter:
public class GenericClass<T> {
}
I can create a variable typed to store an object, with the generic parameter set to, say a String
. Java will also let me assign that variable to another variable but with the generic parameter set to the wildcard <?>
type:
GenericClass<String> stringy = ...
GenericClass<?> generic = stringy; // OK
However, when working with a class with a generic parameter, if you set the type of that parameter to be generic, you can't then assign an object of that class to an identically typed/genericized type where the latter (inner/nested) parameter is of the wildcard type <?>
:
GenericClass<GenericClass<String>> stringy = ...
GenericClass<GenericClass<?>> generic = stringy; // Compile Error
// And just in case that is confusing, a more
// realistic example involving Collections:
List<GenericClass<String>> stringy = ...
List<GenericClass<?>> generic = stringy; // Compile Error
The specific compile error is:
Type mismatch: cannot convert from List<GenericClass<String>> to List<GenericClass<?>>
Intuitively I would think that the assignment in question should not be a problem. So why is this assignment an problem?
The problem your facing is denominated Covariance.
List<GenericClass<String>> stringy = ...
List<GenericClass<?>> generic = stringy;
generic.add(new GenericClass<Integer>());
If this wasn't a compile error, then the last line of code would be possible.
You could get around the error by doing this:
List<? extends GenericClass<?>> generic = stringy;
but you can not use add
also because you don't really know what ? extends GenericClass<?>
is (Covariance once again). In this case you can only enumerate through the List and expect GenericClass<?>
.
Technically, that's because List<GenericClass<String>>
is not a subtype of List<GenericClass<?>>
. In order to make it work, you could do something like
List<? extends GenericClass<?>> generic = stringy
which should work as expected (though is pretty ugly...).
See, for example, this SO question for more details
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With