简述
Java 方法的声明的格式是 修饰符 返回类型 方法名(参数列表){方法体}
。
参数列表中可以有0个或者多个参数,参数的类型可以是基本类型也可以是引用类型,非常灵活,而且,还可以用同名但是参数列表不同的方法组成重载的方法,为程序设计与实现提供了很大的便利。在jdk1.5之后,Java引入了一种新的方法参数列表的声明方式:可变长度参数。
可变长度参数,就是使用一种特殊标记声明方法的参数列表,然后在调用方法的时候,可以传入任意个数的实参。有资料称可变长度参数为“可变参数”,这是有些不妥的,因为实际上“可变”的含义仅仅是参数长度(也可以说是参数个数)是可变的,参数的类型仍然是在声明的时候就唯一确定了(使用Object也是唯一确定的特殊情况)。
可变长度参数声明时,与普通参数的区别就是参数类型的后面紧跟了三个点号。
使用演示
通过一个整数求和的例子演示可变长度参数的使用。
public class Demo {
public static void main(String[] args) {
System.out.println(sum());
System.out.println(sum(1));
System.out.println(sum(1, 2));
System.out.println(sum(4, 6, 1, 3));
}
public static int sum(int... nums) {
int sum = 0;
for (int i : nums) {
sum += i;
}
return sum;
}
}
运行上面的程序,结果符合预期,分别打印了 0,1,3,14。
实现原理
Java 最后将可变长度的参数封装成为一个数组。数组元素的类型就是可变长度参数的类型(即…之前的类型,在上面的例子中就是 int),数组的名称是参数名称(在上面的例子中是 nums)。
使用限制
变长参数给编程带来了很大的便利,但是同时也可能会引发一些新的问题,为了能够正确无歧义地使用变长参数,Java对变长参数做出如下限制:
-
变长参数必须是方法中的最后一个参数,避免无法区分变长参数和普通参数;
public int fun(int... args, int a){} // 错误代码示例
如上面的代码所示,如果有调用
int num = fun(1, 2, 3, 4)
并不能严格地认为123是args参数,4是a参数。 -
一个方法不能定义多个变长参数,避免参数错位;
-
变长参数位置如果被同等类型数组替代,不能构成重载,因为本质上是一个方法。
public static void fun(int...nums) {}
public static void fun(int[] nums) {}
上面的两个方法实际是一个方法,在同一个类中不能通过编译。
数组还是可变长度参数
既然可变长度参数在本质上就是一个数组,在实参传递的时候也可以直接传递一个数组进去,为什么不直接使用数组而要使用可变长度参数呢?
- 在参数个数是0的情况下,如果是数组参数,也必须传递一个元素个数为0的数组。
- 在参数个数很少的情况下,省掉了将参数封装为数组的环节,使用很方便。
使用场景
在上面的使用演示程序中,实现了一个数字相加的功能,因为不确定是多少个数字相加,所以采用了变长参数。
在JDBC的接口定义中,一般会定义查询和更新操作的方法,查询和更新都需要传入预编译的SQL语句以及SQL语句中的占位符参数。接口方法如下:
ResultSet query(String sql, Object...params);
int update(String sql, Object...params);