是什么:
在 Java 5 中提供了变长参数,允许在调用方法时传入不定长度的参数。变长参数是 Java 的一个语法糖,本质上还是基于数组的实现:
public class test{
public static void test(String...args){
//本质上还是基于数组的实现:
for(String arg : args) {//当作数组用foreach遍历
System.out.println(arg);
}
}
public static void main(String[] args) {
test("aa", "bb", "cc");
}
}
使用规则:
- 一个方法只可以有一个变长参数
- 边长参数的位置必须是最后一个
问:找出下面程序存在的问题并只允许修改调用相关代码将其修复好?
public class Demo {
public void print(String str, Integer... args) {}
public void print(String str, String... args) {}
}
//调用
Demo demo = new Demo();
demo.print("hello");
demo.print("hello", null);
答:上面代码直接编译报错,因为调用处对于两个方法都能匹配,编译器不知道选哪个,所以报错了,故别让 null 值和空值威胁到变长方法调用,对于上面调用部分来说修改如下即可运行:
Demo demo = new Demo();
String[] strs = null;
demo.print("hello", strs);
问:分别说说下面程序注释行有问题吗,为什么?
class Base {
void print(String... args) {
System.out.println("Base print.");
}
}
class Sub extends Base {
@Override
void print(String[] args) {
System.out.println("Sub print.");
}
}
Base base = new Sub();
base.print("hello"); //1
Sub sub = new Sub();
sub.print("hello"); //2
答:注释 1 能编译通过且打印为 Sub print.,因为 base引用变量把子类对象 sub 做了向上转型,形参列表是由父类决定的,当然能通过。****编译看左边,运行看右边。【当父类引用变量指向子类对象的时候,会将子类对象向上转型】
注释 2 编译报错为传递的参数 String 类型与方法需要的 String[] 类型不匹配,因为这时编译器看到子类覆写了父类的 print 方法,所以会使用子类重新定义的 print 方法,尽管参数列表不匹配也不会再去父类匹配(
因为找到了就不再找了),故有了类型不匹配的编译错误。---------【针对子类重写了父类方法,用子类变量指向子类对象时调用的情况,先确定方法,再匹配参数】
****先确定该引用变量指向哪一个对象,其次看调用方法,之后再匹配参数列表,看是否回编译通过。
这段代码要特别注意上面子类重写父类的 print 是成立的,因为父类 Base 的 print 方法的 args 变长参数在编译成字节码后的表现是一个 String 数组类型的形参,而子类重写时正是 String[] 类型,
所以自然就是重写而不是重载,故加上 @Override 也没有问题的。
使用场景:在不确定方法需要处理的对象的数量时可以使用可变长参数,会使得方法调用更简单
















