2010-10-16 100 views
0

HI: java中的泛型類型是什麼?只是爲了減少類拋出異常?一般問題

此外,K表示「鍵」,V表示「valuse」,那麼E和T呢?

對於一個泛型類,例如: 名單,我把它理解爲,該列表只能把字符串類型的對象,但我不看好通用的方法相當清楚:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 
    for (T o : a) { 
     c.add(o); // Correct 
    } 
} 

是什麼T表示在上面>?任何人都可以給我一個簡單的闡述?

我看了sun的教程,但是我還不明白。所以我希望有人可以解釋它沒有太多的專業詞彙。

+0

調用T是(只是)一個約定。如果你願意,你可以稱它爲Item(或FuzzyBear)。無論如何,它是該上下文中的「泛型類型」的佔位符(出現在<>的內部)。 – 2010-10-16 06:29:32

+0

我知道,這只是一個例子,但爲此目的,有'Arrays.asList(T ...)'和'Collections.addAll(Collection,T ...)'。 – whiskeysierra 2010-10-16 09:13:37

回答

2

字母E和T分別代表元素和類型,但要注意它們不是由編譯器或類似的東西強制執行的。你幾乎可以放置任何東西,包括完整的單詞,但建議你使用單個大寫字母,因此最好區分它們(小寫字母看起來像變量名稱,以大寫字母開頭的單詞看起來像類,而全大寫單詞看起來像常量)

至於用法,就這樣想。當你創建一個數組時,你可以創建Object[],String[],Integer[],SomeClass[],它告訴你到底有什麼。在引入收藏/地圖類(List,Set,Map)的泛型之前,有一個問題是你可以在其中放置任何東西(有些人可能會認爲這不是問題)。所以現在你可以創建類似於數組的List<String>,List<Object>。雖然有一些差異。例如String[]延伸Object[],但List<String>不延伸List<Object>所以你不能把一個字符串列表實例放在一個對象列表變量。

泛型的優點是你可以在任何類上擁有它們,而一個類可以有多個通用參數(如Map<K, V>)。你可以把它看作給其他類的實例提供的參數Class,告訴它們他們的方法應該接收或返回什麼類型。

是的,關鍵是編譯器可以檢查是否給他們正確的參數類型,以便避免出現在運行時的ClassCastExceptions。例如仿製藥之前,你可以這樣做:

String s = ""; 
List l = new ArrayList(); 
l.add(s); 
Integer i = (Integer)l.get(0); // ClassCastException 

但仿製藥:

String s = ""; 
List<String> l = new ArrayList<String>(); 
l.add(s); 
Integer i = (Integer)l.get(0); // compiler warning: cannot cast from String to Integer 

此外,你可以在一個單一的方法泛型類型參數就像在你的榜樣(類本身不需要有一個類型參數)。這告訴編譯器該方法必須匹配方法參數和/或返回類型的所有類型參數實例。在您的例子稱它想:

String[] a = new String[1]; 
List<Integer> l = new ArrayList<Integer>(); 
fromArrayToCollection(a, l); 

會導致編譯錯誤,因爲該方法必須接受一個T[]Collection<T>,T這裏是相同的。但你給了它一個String[](所以T這裏是字符串)和一個List<Integer>(所以T這裏是Integer,而不是String)。如果我是List<String>雖然,它會工作。 另請注意,List<T>擴展了Collection<T>,因爲List擴展了Collection,但即使T擴展S(無論T和S是什麼),List<T>也不會擴展List<S>

哦,你可以在泛型指定的類限制的可以替代的類型放慢參數通配符:

public <T extends SomeClass> void fromArrayToCollection(T[] a, COllection<T> c); 

這樣,如果你給它SomeClass的[]或SomeChildClass []的方法,將工作(其中SomeChildClass擴展了SomeClass),但不包含Object []或String []。

1

T代表類型。當你實例化一個泛型類時,你必須指定實例中包含的類型。因此,您可以擁有一個String或MyType或WhateverType的集合,而不必擁有對象的集合。

泛型提供了一個類編譯時類型的安全。如果您嘗試將錯誤的數據類型粘貼到通用集合中,您將收到編譯器警告。就我個人而言,我比一英里更喜歡捕捉拋出的異常。此外,與非泛型集合不同,不需要從Generic集合中檢索類型Object。

+0

謝謝。
「static void」這是什麼「T」的行爲?這種方法的返回類型是void,所以我在這裏想知道T的用法。 – hguser 2010-10-16 06:30:14

0

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

聲明「T」是一個通用型某一類而不是名稱。否則,編譯器會查找名稱爲「T」的類。