2013-08-24 126 views
5

陣列什麼是下面的語句之間的區別:轉換泛型

List<E>[] x = (List<E>[]) new List[100]; 

List<E>[] x = new List[100]; 

在我的腳本它指出的是,前者是創建泛型數組的正確方法(儘管它會導致編譯器警告)。但我無法弄清楚(List<E>[])聲明的用法。 List<E>[]甚至不是它自己的類型,編譯器會簡單地(List[])替換它,所以你會得到

List<E>[] x = (List[]) new List[100]; 

List[]List[]轉換,這是沒用的。那麼爲什麼要把(List<E>[])放在第一位呢?

+1

這是code java嗎? – 6502

+1

小心提及語言。 – Malwaregeek

+0

對不起,問題已編輯。不知道接口部分,我只是將它複製出我的腳本,所以我認爲它是有效的代碼。 – user2440792

回答

3

通過在編譯時檢測到更多的錯誤,泛型增加了代碼的穩定性。

這是我給的鏈接的一部分,認爲是重要的,所以我張貼在這裏

這是從接口的定義,一個小摘錄名單 和Iterator在java.util包中:

public interface List <E> { 
    void add(E x); 
    Iterator<E> iterator(); 
} 

public interface Iterator<E> { 
    E next(); 
    boolean hasNext(); 
} 

此代碼應該都不會陌生,除了在角 Brack的東西ETS。這些是接口List和Iterator的formal type parameters的聲明。

類型參數可以在整個泛型聲明中使用,相當多 您可以使用普通類型。

我們知道泛型類型聲明List的調用,如 List。在調用中(通常稱爲參數化的 類型),所有正式類型參數(本例中爲E) 被實際類型參數(在本例中爲Integer)取代。

你可能認爲列表代表一個版本列表 的其中E已經整型被統一更換:

public interface IntegerList { 
     void add(Integer x); 
     Iterator<Integer> iterator(); 
    } 

這種直覺可能是有幫助的,但它也是誤導

這很有幫助,因爲參數化類型列表確實有 的方法看起來就像這個擴展。

這是誤導性的,因爲通用的聲明絕不是 實際上以這種方式擴展。 代碼不存在多個副本 - 不是源代碼,不是二進制文件,也不是磁盤,也不是內存。

泛型類型聲明編譯一勞永逸,轉身 成一個單一的類文件,就像一個普通的類或接口 聲明。

類型參數類似於 方法或構造函數中使用的常規參數。就像一個方法具有形式值 參數一樣,這些參數描述了其操作的值類型,通用的 聲明具有正式的類型參數。當調用方法時, 實際參數將替換形式參數,並對方法體進行評估。

當調用一個通用的聲明中, 實際類型參數代入形式類型參數。這就是泛型的重要性。

你可以看看這裏的more information about Generics

+0

@ user2440792如果您的問題得到解答,請接受答案.. http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Dileep

1

此:

List<E>[] x = new List[100]; 

說x是一個數組類型。該陣列的元素是可容納類型E對象的列表。並且您正在爲其分配一組列表,這些列表可以包含任何對象的任何對象

下一個語句:

List<E>[] x = (List<E>[]) new List[100]; 

是再好不過的。鑄造將無濟於事。這個缺陷仍然是一樣的。

歸根結底,這一切是這樣的藉口:

List<E>[] x = new List<E>[100]; 

和泛型陣列不允許在Java中。因爲數組在運行時保持其元素類型,而通用構造不會。不能有嚴格定義元素類型的數組。

問題是由於定義了一個引用類型List<E>[],根據定義,它不允許在Java中實例化。所以,避免使用這種類型。

你可以使用List列表作爲替代。

1

由於在泛型中存儲在任何集合中的對象類型將在它們被添加到集合的位置進行類型檢查。主要通過泛型,其他人可以理解那些不需要了解泛型的人可以理解的代碼。所以通過在編譯時插入檢查和在運行時擦除啓用此行爲。

你可以看到:http://docs.oracle.com/javase/tutorial/java/generics/