public static void main(String... args)//方法1
它也可以運行.
並且,如果同時還存在
public static void main(String[] args)//方法2
會報已經存在重復的方法的錯誤.
由此可見,String... args跟String[] args對於虛擬機來說其實是壹回事.
而且,在方法內,通過...傳進來的參數的使用方法也跟壹個數組完全無二,可以for循環,甚至可以直接轉換:
public static void main(String... args)
{
String[] ss=args;
}
但對於程序員來說卻還是有差別的.
1.調用
我們只能這樣調用方法2:
main(new String[]{});
即,方法2只能接受String數組做參數.
而我們陌生的方法1可強了,用以下參數調用,照單全收:
main();
main(null);
main(null,null);
main(null,null,null);
......
main("a");
main("a","b");
main("a","b","c");
......
main(new String[]{});
(String...匹配String*,而null也可以是壹個特殊的String)
2.參數位置
使用...的參數只能是最後壹個參數.不然誰知道妳調用的時候,點點點匹配到哪個實參?
public static void main(String[] args,int index)//可以
public static void main(String... args,int index)//不行!
3.重載
假設有以下兩個方法:
public static void main(String... args)//方法1
public static void main(String a,String... args)//方法3
從語法上來看,這個重載完全沒有錯誤,eclipse也沒有報錯.但是當調用時使用的參數個數大於這些方法中點點點參數前面的參數個數時,eclipse就會發現這個錯誤了.很拗口是不是?嘿嘿~還是舉例來說吧.以上這兩個方法,如果調用時
main();
編譯器會認出這個調用的是方法1.但是如果調用時
main("");
編譯器就瘋了...因為壹個String參數,既符合方法1的點點點,也符合方法3的String+點點點,編譯器就不知道調用的是哪個方法了.
String[]參數不會有這種問題.
所以重載時要註意,如果點點點參數前面有跟它類型相同的參數...最好的方法,似乎就是換回數組形式了,要麽就給方法改個名字吧.
4.遇上泛型加外包
用個實例來說
java.util.Arrays是個工具類,所有方法都是靜態的,對數組的操作.裏面有個方法asList(T... args),用來把類型T的數組轉化成List<T>.
這是個很有用的方法,在絕大多數情況下都能如妳所願.
但是,妳可以試試下面的寫法
int[] is=...//自定義的數組,或者從什麽地方獲取來的數組
List<Integer> list=Arrays.asList(is);
很不幸,不要說執行,編譯都通不過.錯誤的意思大概是:
不能將List<int[]>轉化成List<Integer>
明白了吧?
妳的設想是,把int[]中的每壹個元素對應T...中的每壹個點,
可編譯器不這麽想.因為int是原始類型,不是Object的子類.而泛型T隱含的條件是T extends Object.所以編譯器不會把每壹個int看做T,不會把int[]看做T點點點.雖然java已經支持自動將原始類型封包成外包類,但那是單個的情況.
而數組(不管什麽類型)則是壹種特殊的類型,是Object的子類,所以編譯器覺得整個int[]對應壹個T,妳調用的方法是asList<int[]>(int[]... args)而不是妳想象中的asList<Integer>(Integer...)