我在可重用的类中有这样的方法:
public String buildMessageForViolation(ConstraintViolation<?> constraintViolation) {
return constraintViolation.getPropertyPath().toString().replace(".<collection element>", "") + ": " + constraintViolation.getMessage();
}
从另一个类中调用它:
fieldValidator.appendErrorMessage(getUslValidator().buildMessageWithProperty(constraintViolations.iterator().next()) +
(constraintViolations.size() > 1 ? ", and other errors" : ""));
所以,因为我希望在许多类中重复这个块,所以我想重构它,因此复杂性在可重用的类中,而不是在客户端代码中。
因此,我将此添加到可重用的类中:
public String buildMessageForViolations(Set<ConstraintViolation<?>> constraintViolations) {
return buildMessageForViolation(constraintViolations.iterator().next()) +
(constraintViolations.size() > 1 ? ", and other errors" : "");
}
然后将客户端代码更改为:
fieldValidator.appendErrorMessage(getUslValidator().buildMessageForViolations(constraintViolations));
这不编译,说:
The method buildMessageForViolations(Set<ConstraintViolation<?>>) in the type USLValidator is not applicable for the arguments (Set<ConstraintViolation<ClientSpecificClassName>>)
显然,这与我指定“?”的事实有关。对于嵌套类型参数。从我的观点来看,这是合适的,因为可重用的类不关心ConstraintViolation的类型参数。
我能解决这个问题吗?
更新:
我正在阅读发布到此的答案以及随后对答案的编辑,但之后由于某种原因将其删除(猜测响应者放弃了尝试使其正确)。
虽然答案仍然存在,但它至少帮助我找到了一个合理的解决方法。
客户端代码可以改为:
fieldValidator.appendErrorMessage(getUslValidator().buildMessageForViolations(new HashSet<ConstraintViolation<?>>(constraintViolations)));
这至少比原版好一点,尽管还有一些人们必须记住的样板。
答案 0 :(得分:0)
嵌套通配符可能会导致一些意外的不兼容性。试试这个:
public String buildMessageForViolations(Set<? extends ConstraintViolation<?>> constraintViolations) {
答案 1 :(得分:0)
我会把方法写成:
public String buildMessageForViolations(Set<ConstraintViolation> constraintViolations) {..}
这告诉编译器它需要一组任何类型的ConstraintViolation
。我认为在这种情况下,这就是你要告诉编译器的内容。
使用客户端代码:
ConstraintViolation cv = new StringConstraintViolation();
USLValidator uslValidator = new USLValidator();
Set<ConstraintViolation> constraintViolationSet = new HashSet<>();
constraintViolationSet.add(cv);
uslValidator.buildMessageForViolations(constraintViolationSet);