2009-11-17 245 views

回答

34

之間的差異。

第一個聲明應返回其元素類型與參數類相同的集合。編譯器推斷N的類型(如果未指定)。所以,下面的兩個語句中使用第一次申報時是有效的:

Collection<Integer> c1 = getThatCollection(Integer.class); 
Collection<Double> c2 = getThatCollection(Double.class); 

第二個聲明不聲明返回的集合類型參數的參數類之間的關係。編譯器假定他們是不相關的,所以客戶端必須使用返回類型爲Collection<? extends Number>,不管理由是什麼:

// Invalid statements 
Collection<Integer> c1 = getThatCollection(Integer.class); // invalid 
Collection<Double> c2 = getThatCollection(Double.class); // invalid 
Collection<Number> cN = getThatCollection(Number.class); // invalid 

// Valid statements 
Collection<? extends Number> c3 = getThatCollection(Integer.class); // valid 
Collection<? extends Number> c4 = getThatCollection(Double.class); // valid 
Collection<? extends Number> cNC = getThatCollection(Number.class); // valid 

建議

如果確實存在之間的關係在返回的類型參數和傳遞的參數之間鍵入,使用第一個聲明要好得多。如上所述,客戶端代碼更清潔。

如果關係不存在,那麼最好避免第二個聲明。使用有界通配符的返回類型會強制客戶端在任何地方使用通配符,因此客戶端代碼會變得分崩離析且無法讀取。約書亞布洛赫emiffisize,你應該Avoid Bounded Wildcards in Return Types(幻燈片23)。儘管返回類型中有界的通配符可能有用,但在某些情況下,結果代碼的醜陋性應該恕我直言,恕不另行通知。

+3

1爲的差異明確的解釋。小小的狡辯 - 我認爲你假設第一個總是更好的選擇 - 我會說「不用說」更好的選擇取決於上下文。 – 2009-11-17 17:23:11

+0

@Steve謝謝!我補充說明了爲什麼要避免第二種說法。 – notnoop 2009-11-17 17:30:40

+0

+1非常棒的答案! – Stephan 2013-05-22 10:38:22

-3

在這種特殊情況下,沒有。然而第二個選項更靈活,因爲它允許您返回包含不同類型元素(即使它也是Number)的集合,而不是包含collection參數的類型。

具體的例子:

Collection<? extends Number> getRoot(Class<? extends Number> number){ 
    ArrayList<Integer> result=new ArrayList<Integer>(); 
    result.add(java.util.Math.round(number); 
    return result) 
} 
相關問題