Impossible typing when an argument accepts Collection<X<?>>

generics, java, types

Solution

The API is wrong. Unless implementations need to add new `ConstraintViolation<?>`s to the set, it should accept all `Set<? extends ConstraintViolation<?>>`.

Here's an example demonstrating why this is more flexible (provided by Paul Bellora, thanks):

public class Main {

    interface Foo<T> { }

    interface SubFoo<T> extends Foo<T> { }

    static class Bar { }

    public static void main(String[] args) {

        Set<Foo<?>> arg1 = null;
        Set<SubFoo<?>> arg2 = null;
        Set<Foo<Bar>> arg3 = null;
        Set<SubFoo<Bar>> arg4 = null;

        Set<Foo<?>> inflexibleParam;
        inflexibleParam = arg1; //success
        inflexibleParam = arg2; //incompatible types
        inflexibleParam = arg3; //incompatible types
        inflexibleParam = arg4; //incompatible types

        Set<? extends Foo<?>> flexibleParam;
        flexibleParam = arg1; //success
        flexibleParam = arg2; //success
        flexibleParam = arg3; //success
        flexibleParam = arg4; //success
    }
}

(ideone)

Problem

This problem comes from the typing of the constructor of `javax.validation.ConstraintViolationException`. It accepts `Set<ConstraintViolation<?>>` as argument. While it's very easy to get a set of ConstraintViolation<X> where X is a concrete type, it seems impossible to get a set of "ConstraintViolation<?>" from any well-typed API. And it is not possible to convert the former to the latter without using some convoluted casts. (Casting to `Set<? extends ConstraintViolation<?>>` and then to `Set<ConstraintViolation<?>>`.) So do you guys think the API is wrong or I am wrong (and why)?

Original source

Related problems