【笔记53】明智审慎地使用可变参数

从Java 1.5开始就增加了可变参数(varargs)方法,又称作variable arity method。可变参数方法接受0个或多个指定类型的参数。它的机制是先创建一个数组,数组的大小为调用位置所传递的参数数量,然后将值传到数组中,最后将数组传递到方法。

可变参数的机制原理:

1.创建一个array[],它的size就是所传参数的个数;

2.将参数放入到array[]中;

3.将array[]传给方法。

例如,下面就是一个可变参数的求和方法:

// Simple use of varargs - Page 197
    static int sum(int... args) {
        int sum = 0;
        for (int arg : args)
            sum += arg;
        return sum;
    }

如果客户端没有传递参数,需要在运行时检查数组长度:

static int min(int... args) {
      if (args.length == 0)
          throw new IllegalArgumentException("Too few arguments");
      int min = args[0];
      for (int i = 1; i < args.length; i++)
          if (args[i] < min)
              min = args[i];
      return min;
  }

这中解决方案有两个不足:1.如果没有传入参数,就会在运行时而不是编译时失败;2.代码不美观。

有一种更好的方法可以解决这个问题。声明该方法有两个参数,一个是指定类型的正常参数,另一个是这种类型的varargs参数。这个方法弥补了上面示例中的所有不足:

static int min(int firstArg, int... remainingArgs) {
        int min = firstArg;
        for (int arg : remainingArgs)
            if (arg < min)
                min = arg;
        return min;
}

可变参数的适用场景:当真正需要一个方法带有不定数量的参数时,可变参数就非常有效。可变参数是为printf而设计的,它是在jdk5引入的。printf和反射机制都从可变参数中获得极大的收益。但是,它带来便利的同时,也有很多潜在的危险,我们要慎重使用。

1.如果所传参数为null,方法里有对参数的引用(比如 args[0])时,那么就会在运行时失败(编译时却检测不出错误);

2、在重视性能的情况下,使用可变参数机制要特别小心。可变参数方法每次调用都会导致进行一次数组分配和初始化。

如果只是凭经验确定,无法承受这一成本,但是又需要可变参数的灵活性。解决方案如下:假如某个方法95%会调用3个或更少的参数,那么就声明该方法的5个重载,每个重载方法带有0-3个参数,超过3个参数的时候,就会自动调用可变参数方法。

public void foo(){}
public void foo(int a1){}
public void foo(int a1, int a2){}
public void foo(int a1, int a2, int a3){}
public void foo(int a1, int a2, int a3, int... rest){}

像大多数的性能优化方法一样,这种方式看起来很不恰当,但是用到的时候会有很大帮助。

3.在打包作业时,还有一点需要注意。当可变参数的使用发生变动时(比如:以前用可变参数方法,现在用普通方法),所有引用参数列表的类的.class都要重新生成,因为可变参数的array的分配和初始化是在编译期间完成的。

简而言之,在定义参数数目不定的方法时,可变参数方法时一种很方便的方式,但是不应该过度滥用。使用不当,容易产生混乱的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值