No Relation To...


Wednesday, April 29, 2009

Java generics mystery

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.

Labels:

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.

    By Blogger Vivien Barousse, At April 29, 2009 7:21 AM  

  • 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).

    By Blogger Emmanuel Bernard, At April 29, 2009 7:44 AM  

  • 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.

    By Blogger Josh McDonald, At April 30, 2009 2:17 AM  

Post a Comment



Links to this post:

Create a Link

<< Home