2012-01-25 85 views
4

更新:這似乎是Eclipse相關的,而不是哈德森相關的,所以我相應的更新問題。javac編譯不符

在命令行運行Maven的時候,我得到了一些編譯器錯誤,但在我們組所有的開發人員對Eclipse代碼工作正常(一些通用的複雜性,詳情見下文)。這有什麼不同以及如何處理它?

失敗看起來像這樣的代碼:

299 private <T extends ProductClassDTO> List<T> convertProductClass(List<? extends ProductClassDTO> fromList) { 
300  List<T> toList = new ArrayList<T>(); 
301  for (ProductClassDTO from : fromList) { 
302   T to = convert(from); 
303   toList.add(to); 
304  } 
305  return toList; 
306 } 

這是構建服務器上的錯誤:

[ERROR] ...java:[302,26] type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds T,com.volvo.protom.util.dto.ProductClassDTO 

(我知道有其他問題+這個在SO答案,但他們似乎並不適用於這個特定的問題,因爲更改爲T to = <T>convert(from)不起作用,也許我應該做別的事情?)我猜錯誤是指這個類有幾個convert方法,並且多於一個適合?

謝謝!

更新2:這些都是轉換籤名:

private void convert(TestObjectDTO from, TestObjectDTO to); 
private <T extends TestObjectDTO> T convert(TestObjectDTO from); 
private void convert(ProductClassDTO from, ProductClassDTO to); 
private <T extends ProductClassDTO> T convert(ProductClassDTO from); 
private void convert(TestObjectTypeDTO from, TestObjectTypeDTO to); 
private <T extends TestObjectTypeDTO> T convert(TestObjectTypeDTO from); 
+0

這可能是相關的http://stackoverflow.com/questions/314572/bug-in-eclipse-compiler-or-in-javac – stacker

+0

它是,但正如我所說的加入行302不工作在我們開發人員在Windows下使用編譯器 –

+0

「轉換」方法的簽名是什麼? – McDowell

回答

0

Eclipse和JDK javac稍有不同,請參閱@maximdim的評論。始終從命令行運行以確保兼容性(儘管Eclipse的javac似乎更加正確)。

-1

我想這些方法的簽名不應該是什麼。泛型參數出現的泛型方法僅返回類型(如<T extends ProductClassDTO> T convert(ProductClassDTO))通常不是您想要的。

這意味着,調用者調用方法並將結果投射到任何可能的子類型ProductClassDTO是合法的。通常只有一個可能的值滿足這個要求:null。所以轉換方法總是必須返回null以保證類型安全。否則ClassCastException可能會出現在調用代碼中。

請記住,由於類型擦除時,convert方法無法知道調用者希望T是哪種類型的機會,所以他們無法返回根據T值不同類型的實例。

同樣的問題發生在convertProductClass方法,雖然它並不壞在這裏。該方法需要返回一個列表,其中只包含調用者可以自由解釋爲ProductClassDTO的任何子類型的值。唯一的值是null,空列表和僅包含null值的列表。使用列表時,所有其他情況可能導致ClassCastException

你可以做什麼:

  • 如果轉換方法返回總是相同的類型,改變返回 類型的方法,這種類型。
  • 如果呼叫者不關心具體類型,但只需知道它是ProductClassDTO的子類型,則分別將返回類型更改爲ProductClassDTOList<ProductClassDTO>
  • 如果convert方法應根據調用者的願望返回類型的實例,則需要通過將Class<T>的實例作爲附加參數傳遞給所有這些方法來明確告訴它們返回的類型。然後convert方法可以使用此對象來創建適當類型的新實例。
+0

如果我將它分配給ProductClassDTO(它是一個接口)的實現類,它就可以工作。通過類是我想要避免的,因此沒有這樣的事情。如果我想要一些其他類型(通過列表),列表需要投射,這會變得冗長。無論如何,鑄造到T解決了這個問題,所以我會堅持,而不是添加不必要的代碼堆。 –

+0

@Jonas它現在可以正常工作,因爲調用者和轉換方法恰好對'T'使用相同的值。但是你的編譯器會給出警告,因爲當你改變其中的一個時,它可能會破壞(並且當時不會有任何編譯器警告或錯誤,只是運行時出現異常)。所以我建議現在添加代碼,以後再保存一個調試會話。 –

+0

此外,如果調用方和轉換方法都一致,爲什麼不直接使用'ProductClassDTO'作爲返回類型?或者它的實施類型?我從你的解釋中看不到一個理由。 –