2017-06-30 66 views
2

這兩種通用函數之間是否存在任何隱含的區別,還是編譯器將它們視爲相同?這兩個通用函數之間的區別

public static <T extends Number> void test(List<T> list) { 
    for (T t : list) { 

    } 
} 

對戰

public static void test(List<? extends Number> list) { 
    for (Number t : list) { 

    } 
} 

此外,是否有使用一個比其他任何好處?

+0

第一個是[通用方法](https://docs.oracle.com/javase/tutorial/extra/generics/methods.html),而第二個不是。 – QBrute

+0

功能相同。第二個好處是你沒有冗餘類型變量。我認爲編譯器會對它們進行不同的處理,因爲類型變量的數量不同。 –

+0

另外一個很好的閱讀:[何時使用通用方法,何時使用通配符?](https://stackoverflow.com/questions/18176594/when-to-use-generic-methods-and-when-to-use -wild-cards) – azurefrog

回答

3

這些在功能上是相同的。所以,第二個應該是首選的短:當你想返回一些依靠聲明的類型

public static void test(List<? extends Number> list) { 
    for (Number t : list) { 

    } 
} 

第一種更有意義。

例如這個代碼是更靈活的關於返回類型:

public static <T extends Number> List<T> test(List<T> list) { 
    for (T t : list) { 

    } 
    return list; 
} 

,你可以這樣調用它:

List<Integer> integers = ...; 
integers = test(integers); 

,因爲在返回類型中使用聲明的參數化類型,編譯器會根據您分配方法結果的變量類型(必須與類型約束兼容)推斷返回類型。

但由於List<Integer>List<? extends Number>亞型也可以用這樣的方式:

List<Integer> integers = ...; 
List<? extends Number> numbers = test(integers); 

沒有宣佈在列表的返回類型參數化類型,則只能分配方法的結果與List<? extends Number>聲明類型:

public static List<? extends Number> test(List<? extends Number> list) { 
    for (Number t : list) { 

    } 
    return list; 
} 

因此,只有這種方式是有效的:

List<Integer> integers = ...; 
List<? extends Number> numbers = test(integers);