2017-06-22 173 views
1

我有一个可重用的类这样的方法:使用嵌套的“?”调用java方法泛型类型

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

的可能的复制[无法投射到非特异性嵌套类型泛型](https://stackoverflow.com/questions/3575681/cant-cast-to-非特定嵌套类型与仿制药) –

回答

0

嵌套通配符会导致一些意想不到的不兼容性。试试这个:

public String buildMessageForViolations(Set<? extends ConstraintViolation<?>> constraintViolations) { 
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); 
+0

这几乎会很好,但实际上并不成功。这会在客户端调用中出现编译错误。 –

+0

你的客户代码是怎样的? – Mustafa

+0

它在原来的文章中,在“然后将客户端代码更改为:”之后。 –