現在將一個Java數群組轉換為List。可以使用Arrays.toList方法,但是使用幾乎肯定會產生令人討厭的意外。
package com.wordpress.mlangc.arrays;import java.util.Arrays;public class ArraysToList{ public static void main(final String[] args) { System.out.println( Arrays.asList(new String[] { "a", "b" })); System.out.println( Arrays.asList(new Integer[] { 1, 2 })); System.out.println( Arrays.asList(new int[] { 1, 2 })); System.out.println( Arrays.asList(new String[] { "a", "b" }, "c")); }}
由於Javadoc對Arrays.asList的說明相當模糊,對你來說預測出程式的運行結果可能有點困難,下面我們來一步步的揭曉答案:
第9行就像我們根據API所預測的那樣在我們的控制台輸出了“[a,b]”,這正是我們樂意看到的。
第12行也一樣如預期那樣輸出了“[1,2]”。
第15行就不同了,當然這裡不是說15與12的不同,而是一個是int另一個是Integer,因此在我們的控制台列印出了類似這樣的結果“[[I@39172e08]”,這就不再如預期那樣了。我們得到一個包含數組中標識每個元素唯一性的地址串的list,而不是包含兩個Integer對象的list。
看到上面的結果後,對於第18行輸出的類似“[[Ljava.lang.String;@20cf2c80, c]”這樣的結果就不會感到驚奇了。
但是發生了什麼呢?前兩個列印語句與我們預期的結果相同,因Java語言規範規定了調用一個聲明為foo(T… t)的方法,比如foo(new T[]{bar,baz})等同於foo(bar,baz)這樣的調用。在Arrays.asList方法中T是參數類型,因此它必須為一個Object 類型,但是int不是,而int[]卻是。這就是為什麼第16行的聲明等同於 Arrays.asList(new Object[] { new int[] { 1, 2 } })。
Arrays.asList(new Object[] { new int[] { 1, 2 } })
最後也是非常重要的一點,在第19行的聲明從一開始就產生了調用問題。我們告訴編譯器我們需要一個包含String數組和字串的list,正如我們預期的那樣我們得到了我們想要的東西。
到現在為止解釋了這麼多,但是我們還可以從中學到更多的東西:問題的真正來源並不是可變參數設計的很糟糕;相反的我認為這個設計很好。關於這個問題在Effective Java2第 42項規範中已經解釋地很清楚了,Arrays.asList違反了該項規範,事實上Arrays.asList作為一個反面教材,告訴了我們在使用Java的可變參數設計API時為什麼要非常小心。在這裡我不會再重複那篇文章裡的回答,但是你自己確實需要親自去讀一下它,但是考慮到完整性我必須指出 上面有問題的聲明在使用Java1.4的編譯器下編譯的時候就會報錯,這是相當好的。現在我們仍然會使用Arrays.asList,但是為了安全要求我 們知道所面臨的問題的複雜性。下面是在將數群組轉換為lists的時候我們需要遵循的規則,做到這些可以確保沒有任何意外的情況發生:
如果你要將一個數群組轉換為list時最好將其轉換為一個string,使用Arrays.toString代替上面的方法吧。即使對於基本類型的數組該方法也不會出現任何問題。
如果你打算將一個基本類型的數群組轉換為所對應的封裝類型的list,使用Apache Commons Lang吧,關於這個可能你很早就在項目中使用過了,類似下面這樣使用ArrayUtils.toObject:
List<Integer> list = Arrays.asList(ArrayUtils.toObject(new int[] { 1, 2 }));
請注意:一般情況下推薦使用未經處理資料類型數組而不是裝箱後的未經處理資料類型列表。
如果你打算將一個參考型別的數群組轉換為list,可以直接使用Arrays.asList:
List<String> list = Arrays.asList(new String[] { "a", "b" });
不要忘了告訴和你一起工作的人以確保他們不和你犯同樣的錯誤。當然,你也可以選擇僅僅記住那些使用Arrays.asList方法時可能出現問題的地方,並使用普通的for迴圈來代替,但是那會使你的代碼很雜亂,還會帶來效能方面的問題。