2017-06-22 96 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

它在原來的文章中,在「然後將客戶端代碼更改爲:」之後。 –