具有通用 ConstraintViolations 集的异常

Exception with generic set of ConstraintViolations

我正在处理一些使用 JSR-303 验证来测试请求对象的服务代码。我想做的是在包含 ConstraintViolations.

Set 的验证失败时抛出自定义 RuntimeException

我所有的请求对象最终都实现了相同的接口,我们称之为Request。我认为有一个 AbstractRequest 实现了 Request,然后是一堆 AbstractRequest 的实现,例如 MyRequest.

对于例外情况,我正在尝试做的是:

public class RequestViolationException extends RuntimeException {
  private Set<ConstraintViolation<? extends Request>> violations;

  public <T extends Request> RequestViolationException(Set<ConstraintViolation<T>> newViolations) {
    this.violations = newViolations;
  }
}

我这样称呼它:

Set<ConstraintViolation<MyRequest>> violations = validator.validate(myRequest);
if (violations.size() > 0) {
  throw new RequestViolationException(violations);
}

但这不起作用。我在这个主题上尝试了一些其他变体,比如让构造函数采用 Set<ConstraintViolation<? extends Request>>,使 violations 成为 Set<ContraintViolation<Message>>,使 violations 成为 Set<ContraintViolation<Message>>,设置它变成 HashSet<ContraintViolation<Message>> 然后迭代 newViolations,等等。每个都被证明会产生无数不同的编译器错误。我怎样才能拥有 ContraintViolation<T>Set,其中 <T>Request 的某些扩展并让它工作?

您不能使用泛型扩展异常: http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCatch

实际上@JGilardi 是对的,您的构造函数接受 <T extends Request> 但您试图将其分配给实例变量 violations,即 <? extends Request>,这是非法的。请参阅 http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html 详细解释。

要使用相同的 <T extends Request> 参数化实例变量,您必须参数化 class,它再次扩展 RuntimeException,因此不可参数化。 :(