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 也沒有問題的。
使用場景:在不確定方法需要處理的對象的數量時可以使用可變長參數,會使得方法調用更簡單