Java 不允许泛型通配符?
Java wildcard generic not allowed?
所以我想制作一个 util 方法,returns 一个包含 ConstraintValidator
错误的列表。我有这个方法:
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<<ConstraintViolation<T>>
然后:
public static <T> List<String> getViolationsToList(Set<ConstraintViolation<T>> violations) {
可能您正在尝试做这样的事情:
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;
}
进一步挖掘,
OP 没有提到它,但请注意,由于更好的类型推断,代码在 Java 8 中工作。
在 java 8 中,您可以执行以下操作:
return violations.stream().map(Violation::getMessage).collect(Collectors.toList());
哪个优雅一点
泛型是不变的。 Set<ConstraintViolation<UserDto>>
不是 Set<ConstraintViolation<?>>
的子类型,尽管 ConstraintViolation<UserDto>
是 ConstraintViolation<?>
的子类型。这就像 List<String>
不是 List<Object>
的子类型一样,即使 String
是 Object
.
的子类型
您需要在顶层使用通配符才能获得类型参数的多态性:
List<String> getViolationsToList(Set<? extends ConstraintViolation<?>> violations) {
所以我想制作一个 util 方法,returns 一个包含 ConstraintValidator
错误的列表。我有这个方法:
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<<ConstraintViolation<T>>
然后:
public static <T> List<String> getViolationsToList(Set<ConstraintViolation<T>> violations) {
可能您正在尝试做这样的事情:
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;
}
进一步挖掘,
OP 没有提到它,但请注意,由于更好的类型推断,代码在 Java 8 中工作。
在 java 8 中,您可以执行以下操作:
return violations.stream().map(Violation::getMessage).collect(Collectors.toList());
哪个优雅一点
泛型是不变的。 Set<ConstraintViolation<UserDto>>
不是 Set<ConstraintViolation<?>>
的子类型,尽管 ConstraintViolation<UserDto>
是 ConstraintViolation<?>
的子类型。这就像 List<String>
不是 List<Object>
的子类型一样,即使 String
是 Object
.
您需要在顶层使用通配符才能获得类型参数的多态性:
List<String> getViolationsToList(Set<? extends ConstraintViolation<?>> violations) {