简体   繁体   English

不允许使用Java通配符通用吗?

[英]Java wildcard generic not allowed?

So I want to make a util method, that returns a List with errors from ConstraintValidator s. 所以我想制作一个util方法,该方法返回一个列表,其中包含ConstraintValidator的错误。 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. Eclipse建议使用UserDto删除通配符或创建新方法,但是我想使用泛型。

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<?> . 即使ConstraintViolation<UserDto>ConstraintViolation<?>的子类型, Set<ConstraintViolation<UserDto>>也不是Set<ConstraintViolation<?>>的子类型。 This is just like how List<String> is not a subtype of List<Object> , even though String is a subtype of Object . 就像List<String>不是List<Object>的子类型一样,即使StringObject的子类型。

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. OP没有提及它,但是请注意,由于更好的类型推断,该代码在Java 8中有效。

In java 8 you could do the following : 在Java 8中,您可以执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM