Java通配符通用不允许?

时间:2016-02-11 11:25:43

标签: java generics wildcard

所以我想创建一个util方法,它返回一个包含ConstraintValidator s错误的List。我有这个方法:

public static List<String> getViolationsToList(Set<ConstraintViolation<?>> violations) {
    List<String> errors = new ArrayList<>();
    for(ConstraintViolation<?> violation: violations) {
        errors.add(violation.getMessage());
    }

    return errors;
}

但是当我打电话时,

RestUtil.getViolationsToList(violations);

它无法编译。违规类型为:

Set<ConstraintViolation<UserDto>> violations;

任何想法? Eclipse建议使用UserDto删除通配符或创建新方法,但我想使用泛型。

4 个答案:

答案 0 :(得分:2)

使用

Set<<ConstraintViolation<T>>

然后:

public static <T> List<String> getViolationsToList(Set<ConstraintViolation<T>> violations) {

答案 1 :(得分:2)

泛型是不变的。 Set<ConstraintViolation<UserDto>>不是Set<ConstraintViolation<?>>的子类型,即使ConstraintViolation<UserDto>ConstraintViolation<?>的子类型。这就像List<String>不是List<Object>的子类型一样,即使StringObject的子类型。

您需要在顶层使用通配符才能获得类型参数的多态性:

List<String> getViolationsToList(Set<? extends ConstraintViolation<?>> violations) {

答案 2 :(得分:1)

进一步挖掘,

OP没有提及它,但请注意,由于更好的类型推断,代码在Java 8中工作。

在java 8中,您可以执行以下操作:

return violations.stream().map(Violation::getMessage).collect(Collectors.toList());

更优雅

答案 3 :(得分:0)

可能是你想做这样的事情:

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;
    }