【问题标题】:Java wildcard generic not allowed?不允许使用 Java 通配符泛型?
【发布时间】:2016-02-11 11:25:43
【问题描述】:

所以我想创建一个 util 方法,它返回一个来自ConstraintValidators 的错误列表。我有这个方法:

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 删除通配符或创建新方法,但我想使用泛型。

【问题讨论】:

  • 尝试使用:Set&lt;ConstraintViolation&lt;Object&gt; 而不是Set&lt;ConstraintViolation&lt;?&gt;
  • 尝试:设置
  • 这显然不会编译。 ConstraintViolation 不继承 ConstraintViolation,尽管 String 确实继承了 Object。我试过了?扩展对象,但仍然不起作用。
  • @AdamKortylewicz 我想让它通用,适用于所有 dto。硬编码给定的 DTO 不是一个好主意。
  • 那么顶级 DTO 类型叫什么? Dto?

标签: java generics wildcard


【解决方案1】:

泛型是不变的。 Set&lt;ConstraintViolation&lt;UserDto&gt;&gt; 不是Set&lt;ConstraintViolation&lt;?&gt;&gt; 的子类型,尽管ConstraintViolation&lt;UserDto&gt;ConstraintViolation&lt;?&gt; 的子类型。这就像List&lt;String&gt; 不是List&lt;Object&gt; 的子类型,尽管StringObject 的子类型。

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

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

【讨论】:

    【解决方案2】:

    使用

    Set<<ConstraintViolation<T>>
    

    然后:

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

    【讨论】:

    • 没用,但只使用 T 有效。非常感谢。公共静态 List getViolationsToList(Set> 违规) {
    【解决方案3】:

    再深入一点,

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

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

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

    更优雅一点

    【讨论】:

    • 是的,我没有提到该项目是在 java 7 中。
    【解决方案4】:

    也许你正在尝试做这样的事情:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      相关资源
      最近更新 更多