<E>

2013-04-11 25 views
-1

的定義我對於<E>的含義非常困惑。我很困惑什麼將被用來代替E.我被告知類型可以放在那裏,例如Integer或Double。但我也被告知ArrayList或LinkedList可以放在那裏。如果有人可以澄清,將不勝感激。<E>

+0

這只是一個佔位符來表示**任何類型**。 – asgs 2013-04-11 02:35:43

+0

@asgs:我會說它表示任何特定的類型。爲了避免與'?'產生混淆,它表示任何未指定的類型。首先你可以做出假設,但你不能對後者作出假設。 – Jack 2013-04-11 02:41:16

+0

@Jack,完全同意。 – asgs 2013-04-11 02:42:42

回答

3

Etype variable。這是一個特定類型的變量和佔位符。

這種語法與parametric polymorphism一起使用,當您要告訴某個特定的類是通過未指定的類型進行參數化的。

這意味着您可以編寫代碼,它依賴於E是一個特定類型的規範,並且您可以添加一些約束條件給出的規範,例如<E extends MySuperType>。並且您可以使用E在整個類定義中引用泛型類型。

您已被告知正確的:因爲變量無非是一個佔位符,它越能包含具體類型如Double,但即使是ArrayList<Double>或最終也是ArrayList<?>,這是不確定的類型的集合。 ?Java generics中的另一個特殊keyword

+0

謝謝,這是完美的。 – user2268305 2013-04-11 03:13:59

2

<E>是一個類型參數,在Java Generics中使用,指定稍後有用的某種類型。例如,在一個容器類中,當你第一次寫它時,你不知道它會寫什麼,但是你的實現關心的是它的內容。

通常情況下,你會看到這樣的事情:

List somelist = new ArrayList<Integer>(); //or some other type 

這意味着ArrayList將舉行Integers。當然,不管你輸入什麼類型來代替Integer,實現都保持不變,但Java需要你聲明所有引用對象的類型。 (或者你可以偷懶,只說這是一個Object,但打破了類型系統的實用性。)

在其他時候,你可能會看到

class Queue<T> { 
    private LinkedList<T> items = new LinkedList<T>(); 
    public void enqueue(T item) { 
     items.addLast(item); 
    } 
    public T dequeue() { 
     return items.removeFirst(); 
    } 
    public boolean isEmpty() { 
     return (items.size() == 0); 
    } 
} 

(從Javanotes拍攝)。類定義中的變量T捕獲傳入的類型,並且可以使用T來代替傳入的任何類型。例如,方法dequeue返回某個對象,但是具體返回類型爲T,該類型僅在類之後才知道寫入。在方法enqueue中,您希望將一些對象添加到您的隊列中,但特別是類型T,在您實例化類的實例之前,您不知道該對象。

+0

謝謝你的幫助。 – user2268305 2013-04-11 03:14:29

0

< E>是將被傳入的「類型」的佔位符。這是列表將保存的類型。例如arrayList上的實現。當你想創建一個新的數組列表時,你需要傳入列表將要保存的對象類型。

ArrayList示例= new ArrayList();

如果我們分別來看看ArrayList類會是這樣的

公共類的ArrayList < E> {...}

基本上是說,我們將舉行的一些列表「類型「,但該類型必須在編譯時傳入,直到此時纔會知道。

+0

你可能想重寫你的答案。目前還不是很清楚,即「該列表的類型」 - 您的意思是「該列表將包含的對象的類型」...... – 2013-04-11 02:57:36

0

<E>泛型只是泛型類型的佔位符。

這是必要的,因爲你需要某種形式的方法或類,你是爲了利用類型的返回類型等

你會很多的例子,如果你只是需要寫一個參考看看收集API。

通常如果你只有E你可以傳遞任何類型作爲參數。

+0

是的。哎呀...感謝您指出... – Thihara 2013-04-11 03:06:50

0

<E>是一個類型參數。就像變量可以保存值一樣,類型參數保存類型。例如,如果你想創建一個包含任何類型與類型安全兩個值的一類,你會怎麼做:

class Pair<T1, T2> { 
    private final T1 first; 
    private final T2 second; 

    public Pair(final T1 first, final T2 second) { 
     this.first = first; 
     this.second = second; 
    } 

    public T1 first() {return first;} 

    public T2 second() {return second;} 

    public static <A, B> Pair<A, B> of(final A first, final B second) { 
     return new Pair<A, B>(first, second); 
    } 
} 

這裏,我們使用類型參數在兩個地方:一個是類在字段類型上進行抽象,並且爲靜態工廠方法of抽象以對它創建的對的類型進行抽象。我們可以使用這個類像:

public static void main(final String[] args) { 
    final Pair<Integer, String> intStringPair = Pair.of(1, "One"); 
    final int intStringPairFirst = intStringPair.first(); 
    final String intStringPairSecond = intStringPair.second(); 

    final Pair<List<String>, Boolean> listBoolPair = Pair.of(
      Arrays.asList("foo", "bar"), true); 
    final List<String> listBoolPairFirst = listBoolPair.first(); 
    final boolean listBoolPairSecond = listBoolPair.second(); 
} 

在這裏你可以看到的類型intStringPairFirstintStringPairSecondlistBoolPairFirstlistBoolPairSecond正確推斷不涉及任何轉換。

這是爲了讓你開始。有更多的東西,如差異,邊界使用extendssuper和通配符(?),我建議你閱讀關於泛型的教程。