2014-11-17 183 views
0

我有此代碼,差()使用增強的for循環的方法和傳統的for循環

class Test 
{ 
    public static void main(String args[]) 
    { 
     ArrayList<Integer> al=new ArrayList<>(); 
     al.add(1); 
     al.add(2); 
     al.add(3); 
     Integer a[]=new Integer[2]; 
     al.toArray(a); 
     for(int i:a) 
     System.out.println(i); 
     /*for(int i=0;i<a.length;i++) 
     System.out.println(a[i]);*/ 

    } 
} 

上面代碼拋出的NullPointerException但如果我嘗試採取的註釋部分斷,並且評論增強爲循環它將打印null 2次。打印則爲a.length打印2.設置整數數組大小設置爲3將打印123

現在,糾正我,如果我錯了:

1>我的指定者的理解(T [] a)方法,如果數組的大小小於列表中的元素,考慮到這一點,將使用數組指定的大小創建新數組,其中的元素將爲空。我的數組應該看起來像這樣[] = {null,null};

2>增強for循環和傳統for循環之間的區別在於,您無法修改或刪除增強for循環中的單個元素。

但是,這個程序爲什麼會有所不同呢?我只是打印它們,爲什麼增強for循環不打印null並拋出NullPointerException?

+0

你需要使用(一)',而不是在值傳遞指定者的'的返回值。在「參數」的文檔中註明:「a - 如果該集合的元素足夠大,將存儲此集合的元素的數組;否則,爲此分配了一個具有相同運行時類型的新數組」。 https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#toArray%28T[]%29 – msandiford

回答

1

toArray(a)方法返回轉換後的數組,這就是你應該使用的;它沒有使用你的數組,因爲它不夠大。

也就是說,

  1. 如果你的列表的大小是2(和你一樣 提供的方法數組的長度),如果你的數組長度或
  2. 3(相同 爲你想要轉換成數組的列表的大小),

你不需要返回的數組;因此,您的for循環會打印出您想要的內容。

至於NullPointerException,這是因爲自動裝箱從Integerint。也就是說,下面的代碼就不會拋出NPE

for(Integer i : a) 
{ 
    System.out.println(i); 
} 

,同時將下面的代碼(因爲它在你的情況一樣):

for(int i : a) 
{ 
    System.out.println(i); 
} 

至於爲何編譯器的拆箱與上面的增強for循環,想想看 - 數組的內容是boxed整數。您嘗試將它們分配給primitive int引用(對於數組中的每個int,請將其讀取爲),因此唯一的方法是取消裝箱對象。

for(int i : a) 
{ 
    System.out.println(a[i]); 
} 

轉化爲

for(int i = 0; i < a.length; i++) 
{ 
    System.out.println((int) a[i]); // a[i] is null here, so casting causing an NPE 
} 

或更正確地,

for(int i = 0; i < a.length; i++) 
{ 
    System.out.println(a[i].intValue()); // a[i] is null here, causing an NPE 
} 
+0

1>什麼是自動裝箱?我知道自動裝箱和拆箱。 2> autounboxing不會發生在傳統的for循環中嗎? 3>這個查詢的另一個答案說我的數組a的大小是3.我在理解toArray()方法時錯了嗎? – Gpar

+0

'autounboxing'我的意思是''unboxing'''編譯器'代表你做的。你做的2點正是我稱之爲「autounboxing」的原因 - 編譯器爲你做了這件事;在你展示的情況下你不這樣做。而在3>我的意思是你的數組長度至少應該是'3',即'Integer [] a = new Integer [3]'。 – mystarrocks

+0

感謝@mystarrocks我的第一和第二點是清楚的。我的第三點基於JLS中的toArray()方法規範。根據哪個數組最新創建,因爲集合和數組的大小不同,數組的大小比集合的大小小。這個新數組的大小將由集合指定大小還是由數組指定?即在我的程序中,大小爲3或2? – Gpar

0
public <T> T[] toArray(T[] a) 

它需要數組作爲參數的所有元素複製並返回該陣列。如果你的數組足夠大,那麼它會複製,否則在運行時將會分配相同的新數組用於此目的。在你的情況下,a的大小爲2.因此創建了大小爲3的新數組a,並將值複製到此新數組並返回。

第二件事,你正在印刷[我]而不是我。因爲我包含元素值,所以打印我。

是這樣的:

public static void main(String args[]) 
{ 
    ArrayList<Integer> al=new ArrayList<>(); 
    al.add(1); 
    al.add(2); 
    al.add(3); 
    Integer a[]=new Integer[2]; 
    a=al.toArray(a); 
    for(Integer i:a) //or for(int i:a) 
    System.out.println(i); 
}