java不定参数"..."详解

java不定参数"..."详解


在调用某个方法时,若是方法的参数个数事先无法确定该如何处理?例如System.out.printf()方法中并没有办法事先决定要给的参数个数,像是:

?
1
2
3
System.out.printf("%d",10);
System.out.printf("%d %d", 10, 20);
System.out.printf("%d %d %d", 10, 20, 30);

在J2SE 5.0之后开始支持不定长度参数(Variable-length Argument),这可以让您轻松的解决这个问题,直接来看下面的范例:

?
MathTool.java
1
2
3
4
5
6
7
8
9
public class MathTool {
         public static int sum(int ... nums ) { //使用…声明参数
                   int sum = 0;
                   for(int num : nums) {
                            sum += num;
                   }
                   return sum;
         }
}

 
    要使用不定长度参数,在声明参数行时要在类型关键词后加上…,而在sum()方法的区块中可以看到,实际上nums是一个数组,编译器会将参数行的(int … nums)解释为(int[] nums),可以以下范例的方式制定各种长度的参数给方法来使用。



先看两个简单的例子,来感受一下Java的不定长度参数 
第一个例子: 
Java代码   收藏代码
  1. public class VariArgs {  
  2.   
  3.     public static void main(String[] args) {  
  4.         test();  
  5.         test("aaa");  
  6.         test("aaa""bbb");  
  7.         test("aaa""bbb""ccc");  
  8.     }  
  9.   
  10.     public static void test(String... args) {  
  11.         System.out.println(args.getClass());  
  12.         for (String arg : args) {  
  13.             System.out.println(arg);  
  14.         }  
  15.     }  
  16. }  

第二个例子: 
Java代码   收藏代码
  1. public class VariArgs {  
  2.   
  3.     public static void main(String[] args) {  
  4.         test("aaa");  
  5.         test("aaa""bbb");  
  6.         test("aaa""bbb""ccc");  
  7.     }  
  8.   
  9.     public static void test(String arg, String... args) {  
  10.         System.out.println(arg);  
  11.         System.out.println("----------------");  
  12.         for (String s : args) {  
  13.             System.out.println(s);  
  14.         }  
  15.     }  
  16. }  

   读者可以自己运行一下,这个不定长度参数的类型为String[],即字符串数组。 
从上面可以看出,如果一个方法的参数定为不定参数的话,这个参数可以根据参数个数动态生成一个数组,然后传入方法执行。 
    不过,不定参数有两个规定:第一,方法的参数列表中最多只有一个不定长度的参数;第二,就是不定长度的数组的位置必须是最后一个参数。不然不能通过编译。 
    对于第一个规定,是因为如果有多于一个不定长度的参数,当真正调用这个方法的时候,JVM、将不知道前面的不定长度参数有多长, 下一个参数是从哪里开始. 
    对于第二个参数也是一样,编译器不知道不定长度参数的长度,无法确定从哪里开始下一个参数。 
    以下是几种不正确使用不定长度参数的例子,请不要这样写程序: 
Java代码   收藏代码
  1. public static void test(Object... objs, Object obj);  
  2.   
  3. public static void test(Object obj1, Object... objs, Object obj2);  
  4.   
  5. public static void test(Object... objs1, Object... objs2);  

   不定参数的方法可以重载。(大家都知道,重载就是方法名相同,而方法的参数列表不同) 
   下面给出重载的示例: 
Java代码   收藏代码
  1. public class VariArgs {  
  2.   
  3.     public static void main(String[] args) {  
  4.         test("aaa");  
  5.         test("aaa""bbb");  
  6.         test("aaa""bbb""ccc");  
  7.     }  
  8.   
  9.     public static void test(Object... args) {  
  10.     }  
  11.   
  12.     public static void test(String arg, String... args) {  
  13.     }  
  14. }  

   读者如果细心的话,可以看出文章开头给出的两个例子的区别,就是第二个例子比第一个例子的test方法的参数多出了一个String arg,从感觉上没有太大的区别,这有点像编译原理的*和+的区别。第一个test方法指可以有0或N个String做参数,但第二个test方法指至少一个String做为参数。 
   然后结合重载来看,把第一个例子和第二个例子合并成一个类,得到以下代码: 
Java代码   收藏代码
  1. public class VariArgs {  
  2.   
  3.     public static void main(String[] args) {  
  4.         test();  
  5.         test("aaa");  
  6.         test("aaa""bbb");  
  7.         test("aaa""bbb""ccc");  
  8.     }  
  9.   
  10.     public static void test(String... args) {  
  11.         System.out.println(args.getClass());  
  12.         for (String arg : args) {  
  13.             System.out.println(arg);  
  14.         }  
  15.     }  
  16.   
  17.     public static void test(String arg, String... args) {  
  18.         System.out.println(arg);  
  19.         System.out.println("----------------");  
  20.         for (String s : args) {  
  21.             System.out.println(s);  
  22.         }  
  23.     }  
  24. }  

    读者可以编译下这个程序,结果是编译不通过。为什么呢?程序编译到第五行时,不能确定test("aaa")该用第10行的test方法还是第17行的方法,因为两个方法都可以有相同的参数列表。都能精确匹配上参数列表,编译器在这种情况下只好报出编译不能通过的错误。所以在重载这样的方法时,注意参数列表,不要使两个方法可以有同样的参数列表。

你可能感兴趣的:(java)