java 5 新特性——可变参数方法

来源:互联网 发布:cc攻击器源码 编辑:程序博客网 时间:2024/04/30 10:34

 JDK1.5引进了方法的可变参数,受到许多开发人员的青睐。有了这种机制,我们可以写出类似于JavaScript的arguments那样的带任意多个参数的方法。Java的可变参数,可用于普通方法上,也可以用于构造方法上,大大增大了我们所写方法的适用范围。

   

 Java编程人员常常需要为方法定义一个包含多个值的参数。这时可以采用List或数组的形式,如下例所示。
public int add(int[] list) {
int sum = 0;
for (int i=0; i < list.length; i++) {sum += list[i];}
return sum;
}

 也可以将它实现为几个重载的方法,每个方法接受不同数量的int参数。这样做有时可以令方法更容易使用,因为调用代码不需要首先创建一个数组。

public int add(int a, int b) {return a + b;}
public int add(int a, int b, int c) {return a + b + c;}
public int add(int a, int b, int c, int d) {return a + b + c + d;}

 如果只有少量值,这对于调用代码更为方便,因为现在可以使用add(12,14,16)来代替add(new int[] {12,14,16})。但是,编写类似这样的方法存在问题,需要为每种可能的参数组合编写不同版本的方法。如果希望在方法的使用方式上具有最大的灵活性则与其创建一个庞大的具有上千个方法的类,不如对重载的方法接受的参数数量进行很小的限制。

 在Java 5中,可以编写一个方法以使它允许可变数量的参数并让编译器完成将列表包装到一个数组中的操作。虽然内部仍是处理数组,但此时的编译器已隐藏了细节。以下的代码使用可变参数(vararg)重写了add方法。

public int add(int... list) {
int sum = 0;
for (int item : list){ sum += item;}
return sum;
}

   注意,那些奇怪的圆点正是可变参数的实际语法!并且,由于这种改动要用到Java 5,我们也可以趁机使用Java 5增强的for循环语法。一旦按照这种方式编写了方法,可以使用实际数量的参数来调用它!此外,还可以传递一个作为参数的数组(但不允许是List或Collection对象):

add(1,3,5,7,9,11,13,15,17,19,21,23,25);
add(new int[] {12,14,16});


需要注意的是当定义一个参数列表时该语法只能使用一次,并且它必须是最后一项。

 以下的代码不能正常运行,因为可变参数不是最后一项:
public void badMethod(int... data, String comment) { } // wrong!

 必须将此代码改写成以下形式:
public void goodMethod(String comment, int... data) { }

 在一些情况下,在方法定义中使用可变参数可以使方法更简便。这在参数列表包含字面(硬编码)值的情况下尤其如此,如上面的示例中给出的int值。

 

使用可变参数重载时,要注意几个问题:

 

1) 可变参数方法与数组参数方法重载时

 

Java代码 复制代码
  1. public class MethodParams{   
  2.     //带可变参数的方法   
  3.     public void hello(String ...params) {   
  4.         System.out.println("执行带可变参数的方法,参数个数为:" + params.length);   
  5.     }   
  6.     //带数组参数的方法   
  7.     public void hello(String[] params) {   
  8.         System.out.println("执行带数组参数的方法,数组长度为:" + params.length);   
  9.     }   
  10. }  

我们写个测试代码运行一下看看结果如何:

Java代码 复制代码
  1. MethodParams mp = new MethodParams();   
  2. mp.hello("AAA","BBB","CCC");  

  编译时报错:

Java代码 复制代码
  1. MethodParams.java:7: 无法在 MethodParams 中同时声明 hello(java.lang.String[]) 和   
  2.  hello(java.lang.String...)   
  3.         public void hello(String[] params) {   
  4.                     ^   
  5. 1 错误  

结论: JDK不允许存在, 带可变参数的方法和带数组参数的方法在同一类中重载。

可变参数==数组参数? 在带可变参数的方法体时,读取可变参数列表时,就是以数组的方式来读取;

带可变参数的方法可以传入一个数组参数,但带数组参数的方法却不能传入可变参数。

 

 

2) 可变参数方法与可变参数方法重载时

Java代码 复制代码
  1. //带可变参数的方法   
  2. public void hello(String ...params) {   
  3.     System.out.println("执行带可变参数的方法,参数个数为:" + params.length);   
  4. }   
  5. //带固定参数和可变参数   
  6. public void hello(String param1, String ...params) {   
  7.     System.out.println("执行带固定参数和可变参数的方法,参数个数为:" + params.length);   
  8. }  

  测试代码跟上例中一样,编译时报错:

Java代码 复制代码
  1. MethodParams.java:18: 对 hello 的引用不明确,MethodParams 中的 方法 hello(java.l   
  2. ang.String...) 和 MethodParams 中的 方法 hello(java.lang.String,java.lang.String   
  3. ...) 都匹配   
  4.                 mp.hello("AAA","BBB","CCC");   
  5.                   ^   
  6. 1 错误  

 结论:JDK不允许存在,带相同参数类型列表(Type List)的参数列表的方法在同一类中重载。

 

 

3)可变参数方法与无参数方法重载时

Java代码 复制代码
  1. //带可变参数的方法   
  2. public void hello(String ...params) {   
  3.     System.out.println("执行带可变参数的方法,参数个数为:" + params.length);   
  4. }   
  5. //不带参数的方法   
  6. public void hello() {   
  7.     System.out.println("执行不带参数的方法");   
  8. }  

我们都知道,可变参数即可带0个或者多个参数,如果带0个参数即不带参数时,JDK会怎么处理呢?

那我们就以执行"mp.hello()"来测试一下。编译通过,运行正常,调用的还带参数的hello()方法。

结论:当可变参数方法与不带参数的方法重载时,JDK默认调用的是无参数的方法。若类中没有定义无参数的方法,则会调用可变参数的方法。

原创粉丝点击