2013-06-28 21 views
0

我Java 6中能聲明數組列表如下在Java 6的右邊使用泛型?

WAY1:使用泛型上的右手側,即<Integer>

List<Integer> p = new ArrayList<Integer>(); 

Way2:使用金剛石操作者

List<Integer> p = new ArrayList<>(); 

Way3:使用通用只在左側

List<Integer> p = new ArrayList(); 

我更喜歡使用方式3作爲它的簡介。這些方式有什麼區別嗎?我們應該選擇哪一個,爲什麼?

更新: -我知道在Java 7第二種方式是建議,但我的問題是在Java的情況下6.哪一個是可取的?

對我來說,方式3也說p是整數列表整數(同樣由way1傳送)。所以我發現除了IDE顯示警告消息之外沒有任何區別:

ArrayList是一種原始類型。引用泛型類型ArrayList<E>應該是參數

+1

注意[diamond-operator]標籤中的信息已經回答你的問題。只需將鼠標懸停在此標籤上並閱讀其說明的第一句話:*鑽石操作符(<>)在Java SE 7中引入*** –

+0

其實我的意思是右側的泛型。看到我的更新 –

+0

*這是什麼部分*自Java 7 *以來可用的鑽石算子,你仍然不明白?這就像在Java 1.4或之前使用泛型一樣:它不存在,所以你不能在那裏使用泛型。 –

回答

5

正如已經指出的,方法2在1.6中是無效的。所以問題是,方式1和方式3是否有區別?除了可讀性,否。

把這個代碼:

import java.util.*; 
class G { 
    public static void main(String [] args){ 
    List<Integer> listOne = new ArrayList<Integer>(); 
    listOne.add(1); 
    int one = listOne.get(0); 

    List<Integer> listTwo = new ArrayList(); 
    listTwo.add(1); 
    int two = listTwo.get(0); 
    } 
} 

編譯並使用javap -c

public static void main(java.lang.String[]); 
    Code: 
    // FOR listOne 
     0: new   #2     // class java/util/ArrayList 
     3: dup   
     4: invokespecial #3     // Method java/util/ArrayList."<init>":()V 
     7: astore_1  
     8: aload_1  
     9: iconst_1  
     10: invokestatic #4     // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
     13: invokeinterface #5, 2   // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 
     18: pop   
     19: aload_1  
     20: iconst_0  
     21: invokeinterface #6, 2   // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object; 
     26: checkcast  #7     // class java/lang/Integer 
     29: invokevirtual #8     // Method java/lang/Integer.intValue:()I 
     32: istore_2  
    // FOR listTwo 
     33: new   #2     // class java/util/ArrayList 
     36: dup   
     37: invokespecial #3     // Method java/util/ArrayList."<init>":()V 
     40: astore_3  
     41: aload_3  
     42: iconst_1  
     43: invokestatic #4     // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
     46: invokeinterface #5, 2   // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 
     51: pop   
     52: aload_3  
     53: iconst_0  
     54: invokeinterface #6, 2   // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object; 
     59: checkcast  #7     // class java/lang/Integer 
     62: invokevirtual #8     // Method java/lang/Integer.intValue:()I 
     65: istore  4 
     67: return   
} 

我們可以看到完全相同的字節碼是在兩種情況下產生的字節碼的樣子。請注意,因爲編譯器中未泛化Generics,所以在編譯時檢查該信息並在checkcast中添加說明以確保在檢索對象安全時執行的強制轉換。

+0

如果way1和way3完全相同,爲什麼警告「ArrayList是一個原始類型。對泛型類型ArrayList 應該被參數化的引用」在引路3中引發,儘管不會引發路徑1?警告對我沒有任何意義。是嗎? –

+0

警告由編譯器給出,因爲它不認爲它包含所有信息。與其他編程語言不同,Java中沒有類型推斷。但是,您已經提供了足夠的信息來生成相同的代碼,因爲它是左邊的通用類型,它告訴編譯器引入'checkcast'。 – selig

+0

Way1和Way3可能會編譯成相同的字節代碼(謝謝您輸入擦除!),但編譯期間這些不一樣。對於java中的所有泛型類型信息都是如此:類型僅提供編譯時類型檢查。有關way1和way3的不同方式的更多信息,請參見[這個答案](http://stackoverflow.com/a/4167148/225217) –

1

沒有區別,如果你使用的是Java 7傾向於第二種方法,但它是不是在Java 6可這是一個new addition到Java 7

+0

一些燈我知道在Java 7發送方式建議。但我的問題是在Java的情況下6.哪一個是可取的?查看我的更新。 –

0

兩者都是相同的,但way2可從Java 7

4

第二種方式是不可能在Java中6,在Java 7中

+0

這是錯字錯誤糾正它。 –

0

方式3使用原始類型。你不應該使用原始類型。它們只能用於傳統代碼。

+0

對我來說,方式3還表示p是一個整數列表(由way1傳遞)。所以我發現除了IDE顯示有關原始類型的警告消息之外,沒有任何區別。以方式3,我們也不能在arraylist p中添加字符串。所以我不明白「Way 3使用原始類型」的說法。當我清楚地宣佈它是整數列表的整數列表。 –

0

方式3不好。混合泛型和原料類型是調皮的,因爲你正在爲有關類型的運行時的假設,並能碰上類似下面的代碼的ClassCastExceptions:

ArrayList b = new ArrayList(); 
b.add(5); 
ArrayList<String> a = new ArrayList(b); 
System.out.println(a.get(0)); 

所以對於Java 6中,總是使用方式1