目录
在 Java 5 中提供了变长参数,允许在调用方法时传入不定长度的参数。变长参数是 Java 的一个语法糖,本质上还是基于数组的实现:
void foo(String... args);
void foo(String[] args);
//方法签名
([Ljava/lang/String;)V // public void foo(String[] args)
定义方法
在定义方法时,在最后一个形参后加上三点 …,就表示该形参可以接受多个参数值,多个参数值被当成数组传入。上述定义有几个要点需要注意:
-
可变参数只能作为函数的最后一个参数,但其前面可以有也可以没有任何其他参数
-
由于可变参数必须是最后一个参数,所以一个函数最多只能有一个可变参数
-
Java的可变参数,会被编译器转型为一个数组
-
变长参数在编译为字节码后,在方法签名中就是以数组形态出现的。这两个方法的签名是一致的,不能作为方法的重载。如果同时出现,是不能编译通过的。可变参数可以兼容数组,反之则不成立
public void foo(String...varargs){}
foo("arg1", "arg2", "arg3");
//上述过程和下面的调用是等价的
foo(new String[]{"arg1", "arg2", "arg3"});
J2SE 1.5 中新增了"泛型"的机制,可以在一定条件下把一个类型参数化。例如,可以在编写一个类的时候,把一个方法的形参的类型用一个标识符(如T)来代表, 至于这个标识符到底表示什么类型,则在生成这个类的实例的时候再行指定。这一机制可以用来提供更充分的代码重用和更严格的编译时类型检查。不过泛型机制却不能和个数可变的形参配合使用。如果把一个能和不确定个实参相匹配的形参的类型,用一个标识符来代表,那么编译器会给出一个 "generic array creation" 的错误
public class Varargs {
public static void test(String... args) {
for(String arg : args) {//当作数组用foreach遍历
System.out.println(arg);
}
}
//Compile error
//The variable argument type Object of the method must be the last parameter
//public void error1(String... args, Object o) {}
//public void error2(String... args, Integer... i) {}
//Compile error
//Duplicate method test(String...) in type Varargs
//public void test(String[] args){}
}
可变参数的基本概念:
Java允许将同一个类中的多个同名同功能 但 参数个数不同的方法 ,封装成一个方法。
可变参数的基本语法:
访问修饰符 返回类型 方法名 (数据类型……形参名){}
可变参数方法的调用
调用可变参数方法,可以给出零到任意多个参数,编译器会将可变参数转化为一个数组。也可以直接传递一个数组,示例如下:
public class Varargs {
public static void test(String... args) {
for(String arg : args) {
System.out.println(arg);
}
}
public static void main(String[] args) {
test();//0个参数
test("a");//1个参数
test("a","b");//多个参数
test(new String[] {"a", "b", "c"});//直接传递数组
}
}
练习:
计算 2 个数的和,3 个数的和,4,5
代码实现:
public class VarParameter01 {
public static void main(String[] args) {
HMethod m = new HMethod();
System.out.println(m.sum(1, 5, 100));
System.out.println(m.sum(1, 19));
}
}
class HMethod {
//可以计算 2 个数的和,3 个数的和,4,5
// 可以使用方法重载
// public int sum(int n1, int n2) {//2 个数的和
// return n1 + n2;
// }
//
// public int sum(int n1, int n2, int n3) {//3 个数的和
// return n1 + n2 + n3;
// }
//
// public int sum(int n1, int n2, int n3, int n4) {//4 个数的和
// return n1 + n2 + n3 + n4;
// }
//……
// 上面三个方法名称相同,功能相同,参数个数不同 -> 使用可变参数优化
//1. int... 表示接受的是可变参数,类型是 int ,即可以接收多个 int(0-多)
//2. 使用可变参数时,可以当做数组来使用 即 nums 可以当做数组
//3. 遍历 nums 求和即可
public int sum(int... nums) {
// System.out.println("接收的参数个数=" + nums.length);
int res = 0;
for (int i = 0; i < nums.length; i++) {
res += nums[i];
}
return res;
}
}
结果:
可变参数的注意事项:
注意事项和使用 细节
1. 可变参数的实参可以为0个或任意多个
2. 可变参数的实参可以为数组
3. 可变参数的本质就是数组
4. 可变参数可以和普通类型的参数一起放在形参列表, 但必须保证可变参数在最后
5. 一个形参列表中只能出现一个可变参数
下面举例:
例子:
public class VarParameterDetail {
public static void main(String[] args) {
//可变参数的实参可以为0个或任意多个
int[] arr = {1, 2, 3};
TT t1 = new TT();
t1.f1(arr);
}
}
class TT {
public void f1(int... nums) {
System.out.println("长度=" + nums.length);
}
//细节: 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
public void f2(String str, double... nums) {
}
//一个形参列表中只能出现一个可变参数
//例如 :下面的写法是错误的
public void f3(int...nums1, double... nums2) {
}
}
练习:
有三个方法 ,分别实现返回姓名和两门课成绩(总分) , 返回姓名和三门课成绩(总分),返回姓名和五门课成绩(总分)。 封装成一个可变参数的方法
分析:
1. 方法名 showScore
2. 形参(String,double……)
3. 返回String
public class VarParameterExercise {
public static void main(String[] args) {
HHMethod h = new HHMethod();
System.out.println(h.showScore("milan", 90.1, 80.0));
System.out.println(h.showScore("terry", 90.1, 80.0, 30.5, 34));
}
}
class HHMethod {
public String showScore(String name, double... scores) {
double totalScore = 0;
for (int i = 0; i < scores.length; i++) {
totalScore += scores[i];
}
return name + "有" + scores.length + "门课的成绩总分为=" + totalScore;
}
}
结果: