2010-05-20 52 views
5

瀏覽通過Guava庫只見從文件類readlines方法方法,這種怪異的簽名:Java的泛型怪異的返回類型

public static <T> T readLines(File file, 
          Charset charset, 
          LineProcessor<T> callback) 

我知道在Java泛型一點點,但是這把我難倒了。

雙T在這裏意味着什麼?爲什麼是第一個角度括號?

UPDATE:謝謝你的回答。我仍然不清楚爲什麼我應該在括號內使用T。爲什麼例如不能將其僅僅是:

public static <> T readLines() 

pulibc static <K> T readLines() 

抑或是Java語法決定了相同的字母必須使用?

現在this甚至wierder:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 

的方法怎麼能有一個通用的返回類型,是無效的?

+0

尖括號中的T不是返回類型;它是該方法的類型參數。 – 2010-05-20 20:55:58

+0

請注意,如果上述簽名中沒有,編譯器自然會期望在某處找到「class T {...}」。有些東西必須告訴編譯器,你希望有一個名爲T的*類型參數*。這就是方法。 – 2010-05-20 21:02:38

回答

3

我還不清楚爲什麼我應該在括號內使用T。爲什麼例如不能將其僅僅是:

public static <> T readLines() 

public static <K> T readLines() 

抑或是Java語法決定了相同的字母必須使用?

<T><K>是類型參數。如果你寫<K> T,那麼T不是一個類型參數 - 相反,你使用的是特定的class T。如果您沒有在範圍內命名爲T的課程,則這不起作用。

現在,這是連wierder:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 

的方法怎麼能有一個通用的返回類型,是無效的?

它不; <T>不是「通用返回類型」,它只是該方法的類型參數。你說的方法是通用的,T是類型參數。該方法的返回類型爲void

+0

這是我正在尋找的句子:「你說的方法是通用的,而T是類型參數。」謝謝! – drozzy 2010-05-21 14:55:01

7

尖括號內的第一個T表示方法本身是通用的。第二個T是返回類型。 T可以是其範圍內的任何類型。在這種情況下,T沒有界限。

T將在呼叫地點確定,在這種情況下,從LineProcessor <T>參數中推斷。

9

這是一個泛型方法 - 在T稱爲類型參數,並且可以代表任何類型。所以,如果我有這個簽名的方法:

public <T> T foo(T[] bar) 

我可以調用它的任何陣列上,它會返回相同類型的單個對象。如果我將它傳遞給一個String數組,我將返回一個String,依此類推。記住在回答你的問題更新,熊市第一<T>不返回類型的一部分:更多信息in the Sun tutorials for "generic methods".

編輯它只是一個指標,T是一個類型參數。所以看你報的例子:這僅僅意味着fromArrayToCollection將接受任何陣列和任何集合,他們必須是同一類型的數組和收集

static <T> void fromArrayToCollection(T[] a, Collection<T> c) 

。因此,您可以通過String[]Collection<String>Integer[]Collection<Integer>,但不通過String[]Collection<Integer>。無論您輸入什麼類型的T,該方法都不會返回任何內容。

+0

謝謝,請參閱我的問題更新 – drozzy 2010-05-20 19:50:38

0

這是一種通用的方法。

實際上有三個Ts,第三個在LineProcessor<T>上指定T的時候使用該方法。

3

而不是在類級別通用只讀方法readLines使用泛型。

  • 第一<T>聲明由該方法
  • 下面的T是返回類型使用的通用的類型。

第一個使用與泛型類相同的語法來聲明泛型。相反,你可以寫

class Generic <T> 
{ 
public static T readLines(File file, 
          Charset charset, 
          LineProcessor<T> callback) 
} 

但是,這將使該類的所有實例通用。

擴展示例:

public static <ElementType,ListType extends List<ElementType>> ListType add(ListType list,ElementType elem) 
{ 
    list.add(elem); 
    return list; 
} 
ArrayList<String> = add(add(new ArrayList<String>(),"Hello"),"World"); 

的方法,增加了一個給定的元素到一個列表,並返回列表。
該方法使用兩種通用類型,一種用於列表元素,另一種用於列表本身。
使用的名稱沒有什麼特別的,對於泛型使用T就像使用i作爲整數。

  • 的ElementType是用於元件的通用類型(任何有效的變量名/標識符可以被使用)
  • ListType是爲通用列表類型的名稱,所使用的類必須擴展名/實現ElementType的List。

該示例調用方法以:

  • 的ElementType =字符串
  • ListType = ArrayList的

這將導致
public static ArrayList<String> add(ArrayList<String> list, String elem)

鼓脹症端:-)

+0

謝謝,這使得它更清晰......但爲什麼我必須在括號內使用字母「T」,而不是像字母「K」或「B」或在所有(即只是空括號)。 – drozzy 2010-05-20 19:52:06

+0

字母T只是一個名稱,< and >之間的名稱僅聲明所用通用類型的名稱。您可以使用3個泛型類型聲明一個方法,如公共靜態 ExtraType someMethod(TypeA var1,AnOtherTypeB var2,ExtraType var3)。 – josefx 2010-05-20 20:29:45