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)?