Java基礎:五、可變參數列表 (9)
- 2020 年 3 月 17 日
- 筆記
由於所有的類都直接或間接繼承於Object類,所以可以創建以Object數組為參數方法,以此獲取可變參數列表
// JavaSE5之前 class A{} public class VarArgs{ static void printArray(Object[] args){ for(Object obj : args){ System.out.println(obj + ""); } System.out.println(); } public static void main(String[] args){ printArray(new Object[]{new Integer(47),new Float(3.14),new Double(11.11)}); printArray(new Object[]{"one","two","three"}); printArray(new Object[]{new A(),new A(),new A()}); } }
// JavaSE5增加的新特性,可以使用它們來定義可變參數列表 class A{} public class NewVarArgs{ static void printArray(Object... args){ for(Object obj : args){ System.out.println(obj + ""); } System.out.println(); } public static void main(String[] args){ printArray(new Integer(47),new Float(3.14),new Double(11.11)); printArray("one","two","three"); printArray(new A(),new A(),new A()); printArray((Object [])new Integer[]{1,2,3,4,5}); printArray(); // Empty list is ok } }
有了可變參數,就再也不用顯式地編寫數組語法了,當你指定參數時,編譯器實際上會為你去填充數組。此時仍舊是一個數組。但是,這不僅僅只是從元素列表到數組的自動轉換,printArray((Object [])new Integer[]{1,2,3,4,5});
中Integer數組(通過使用自動包裝而創建的)被轉型為一個Object數組,並且傳遞給printArray(),此時,它已經是個數組了,所以不會在其上執行任何轉換。因此,如果有一組事物,可以把它們當作列表傳遞,而若果你已經有了一個數組,該方法可以把它們當作可變參數列表來接受
** 傳遞0個參數**
public class OptionalTrailingArguments{ static void f(int required,String... trailing){ // 可變參數列表可以使用任何類型的參數,包括基本類型 System.out.println("required: " + required + " "); for(String s : trailing){ System.out.println(s + " "); } System.out.println(); } public static void main(String[] args){ f(1,"one"); f(2,"two","three"); f(1); } }
可變參數列表可以使用除Object之外類型的任何類型的參數,包括基本類型。
public class VarargType{ static void f(Character... args){ System.out.print(args.getClass); System.out.println(" length " + args.length); } static void f(int... args){ System.out.print(args.getClass); System.out.println(" length " + args.length); } public static void main(String[] args){ f('a'); f(); // 如果在列表中沒有任何元素,那麼轉變成的數據的尺寸為0 g(1); g(); System.out.println("int[]: " + new int[0].getClass()); } }
getClass()方法屬於Object的一部分,它將產生對象的類,並且在列印該類時,可以看到表示該類類型的編碼的字元串。前面的"[" 表示這是一個後面緊隨的類型的數組,而緊隨的「I」表示類型為int。這樣也驗證了使用可變參數列表不依賴自動包裝i 只,而實際上使用的是基本類型
public class AutoboxingVarargs{ public static void f(Integer... args){ for(Integer s : args){ System.out.print(i + " "); } System.out.println(); } public static void main(String[] args){ f(new Integer(1),new Integer(2)); f(4,5,6,7,8,9); f(10,new Integer(11),12);// 可以在單一的參數列表中將類型混合在一起,而自動包裝機制將有選擇地將int參數提升為Integer } }
可變參數列表使得重載過程變得複雜了,下面的例子中,編譯器都會使用自動包裝機制來匹配重載的方法,然後調用最明確匹配的方法,但是在不使用參數調用f()時,編譯器就無法直到應該調用哪一個方法了。可以給所有方法增加一個非可變參數,但是建議的是 只在重載方法的一個版本上使用可變參數列表,或者壓根不用它
public class OverloadingVarargs{ static void f(Character... args){ for(Character c : args){ System.out.print(c + " "); } System.out.println(); } static void f(Integer... args){ for(Integer c : args){ System.out.print(i + " "); } System.out.println(); } static void f(Long... args){ System.out.println("third"); } public static void main(String[] args){ f(a,b,c); f(1); f(2,1); f(0); f(0L); // f(); // 無法調用 } }