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