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 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 也没有问题的。
使用场景:在不确定方法需要处理的对象的数量时可以使用可变长参数,会使得方法调用更简单