Here is a puzzle for Generics gurus.
Can somebody explain why
Set<Address> addresses = new HashSet<Address>();
Set<?> things = addresses;
compiles but
Set<ConstraintValidator<Address>> validatedAddresses =
new HashSet<ConstraintValidator<Address>>();
Set<ConstraintValidator<?>> validatedThings =
validatedAddresses;
does not compile?
More specifically, the assignment on the second line breaks.
3 comments:
That's because ConstraintValidator<?> is not equals to ConstraintValidator<Address>. Parametrized types are expected to be strictly equals.
You can solve this issue by using generic wildcards :
Set<? extends ConstraintValidator<?>> validatedThings = validatedAddresses;
This is discussed more in the Java language specification, §4.5.
Yes but the surprising thing is that I can do
ConstraintValidator<Address> a;
ConstraintValidator<?> thing = a;
But as soon as I use a Set<ConstraintValidator<Address>> which is a container of ConstraintValidator<Address>, I cannot assign it to Set<ConstraintValidator<?>>
Set<? extends ConstraintValidator<?>> works but it seems to imply that ? extends ConstraintValidator<?> contains ConstraintValidator<Address> while a plain ConstraintValidator<?> does not (which contradicts my first statement).
Set<SubClass> extends Set<?>, but it doesn't extend Set<BaseClass>. Annoying, but the way of things.
Replace SubClass with Set<OtherClass>, and BaseClass with Set<?>. Even though Set<OtherClass> extends Set<?>, Set<Set<OtherClass>> will still not extend Set<Set<?>>. Given the first situation, I think it would be strange to expect otherwise.
Post a Comment