Java Generics:一组泛型类型对象的函数参数

时间:2014-03-24 08:42:36

标签: java generics hibernate-validator

我正在使用javax.validation / Hibernate验证。 要验证带注释的(例如属性为@NotNull)bean,hibernate验证器与javax.validation接口一起使用:

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

public interface Validator {
    <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups);
}

public interface ConstraintViolation<T> {
    String getMessage();
    Path getPropertyPath(); 
    T getRootBean();
}

目标是编写一个方法,接受不同类型的集合,例如:

Set<ConstraintViolation<TaskList>> violationsTaskList = validator.validate(taskList);
Set<ConstraintViolation<TaskItem>> violationsTaskItem = validator.validate(taskItem);

public void consumeViolations(Set<ConstraintViolation<?> violations) {
    // Do something meaningful...
    violations.getMessage();
}

使用通配符?最好想到我想到了,但编译器拒绝了它:

consumeViolations(....<?>) cannot be applied to consumeViolations(....<TaskList>)

我不想为每个类型T编写此方法只是为了调用getMessage()并将其传递给下一个方法。

是否可以编写这样的方法?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T,如String getMessage()。

1 个答案:

答案 0 :(得分:1)

我认为你需要的是

public void consumeViolations(Set<? extends ConstraintViolation<?>> violations) {}

或喜欢

public <T, V extends ConstraintViolation<T>> void consumeViolations(Set<V> violations) {}

取决于您需要对方法内的Set进行操作。

这只是泛型的常规行为,通常不是协变的。您可能知道a List<Dog> is not a List<Animal>同样适用于此。