在异常的参数中使用泛型

Tau*_*ren 10 java generics exception

我正在尝试将一组通用对象存储在一个中,Exception并且在弄清楚泛型时遇到了麻烦.具体来说,我正在使用Hibernate Validator,并希望将收集的违规列表保存在异常中,以便在应用程序的另一层中进行处理.这是一个例子:

Set<ConstraintViolation<User>> violations = validator.validate(user);
if (violations.size() > 0) {
    throw new ValidationException("User details are invalid", violations);
}
Run Code Online (Sandbox Code Playgroud)

在Eclipse中,该throws行显示构造函数未定义,并建议我将构造函数签名更改为ValidationException(String, Set<ConstraintViolation<User>>.这是ValidationException:

public class ValidationException extends Exception {
    private Set<ConstraintViolation<?>> violations;

    public ValidationException() {
    }
    public ValidationException(String msg) {
        super(msg);
    }
    public ValidationException(String msg, Throwable cause) {
        super(msg, cause);
    }
    public ValidationException(String msg, Set<ConstraintViolation<?>> violations) {
        super(msg);
        this.violations = violations;
    }
    public Set<ConstraintViolation<?>> getViolations() {
        return violations;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我想保留ValidationException通用,以便我可以使用它而不仅仅是User验证.我也尝试Set<ConstraintViolation<? extends Object>>过,但得到的结果相同.

有没有办法完成我想要做的事情?

Col*_*inD 12

您需要将违规设置参数声明为Set<? extends ConstraintViolation<?>>:

public ValidationException(String msg, 
                           Set<? extends ConstraintViolation<?>> violations) {
  super(msg);
  this.violations = Collections.unmodifiableSet(
      new HashSet<ConstraintViolation<?>>(violations));
}
Run Code Online (Sandbox Code Playgroud)

然后一切都应该按预期工作.

这具有防御性地复制Set您所给予的额外好处,确保Set不能更改异常的内部.