So I want to make a util method, that returns a List with errors from ConstraintValidator
s. I have this method:
public static List<String> getViolationsToList(Set<ConstraintViolation<?>> violations) {
List<String> errors = new ArrayList<>();
for(ConstraintViolation<?> violation: violations) {
errors.add(violation.getMessage());
}
return errors;
}
However when I call it,
RestUtil.getViolationsToList(violations);
It does not compile. Violations is of type:
Set<ConstraintViolation<UserDto>> violations;
any ideas? Eclipse suggest to remove the wildcard with UserDto or create new method, but I want to use generics.
Use
Set<<ConstraintViolation<T>>
Then:
public static <T> List<String> getViolationsToList(Set<ConstraintViolation<T>> violations) {
Generics are invariant. Set<ConstraintViolation<UserDto>>
is not a subtype of Set<ConstraintViolation<?>>
, even though ConstraintViolation<UserDto>
is a subtype of ConstraintViolation<?>
. This is just like how List<String>
is not a subtype of List<Object>
, even though String
is a subtype of Object
.
You need a wildcard at the top level in order to get polymorphism of type arguments:
List<String> getViolationsToList(Set<? extends ConstraintViolation<?>> violations) {
To dig a bit further,
OP does not mention it, but note that the code is working in Java 8 due to better type inference.
In java 8 you could do the following :
return violations.stream().map(Violation::getMessage).collect(Collectors.toList());
which is a bit more elegant
May be you are trying to do something like this :
public static <T> List<String> getViolationsToList(Set<ConstraintViolation<T>> violations) {
List<String> errors = new ArrayList<>();
for(ConstraintViolation<T> violation: violations) {
errors.add(violation.getMessage());
}
return errors;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.