面試合集:https://gitee。com/mydb/interview
可選引數(varargs)是 JDK 5 中新增的特性,也叫變長引數或可變引數。它是指一個方法的引數中可以用“。。。”來表示此方法可以接受無窮個引數,這種表示方法就叫可選引數。
可選引數的語法如下:
public void method(資料型別。。。 引數名稱){ // 方法體}
可選引數基本用法如下:
public class ArgumentExample { public static void main(String[] args) { // 呼叫可選引數 method(“Java”); System。out。println(); // 呼叫可選引數 method(“MySQL”, “Redis”); // 呼叫可選引數 System。out。println(); method(“Spring”, “Spring MVC”, “Spring Boot”); } /** * 可選引數方法 */ public static void method(String。。。 names) { for (String item : names) { System。out。println(item); } }}
以上程式的執行結果如下圖所示:
固定引數
固定引數的概念恰好與可選引數相反,固定引數也就是普通的引數,一個方法中有固定的引數型別和個數且沒有“。。。”修飾就是固定引數。JDK 5 之前所有的方法傳參都是固定引數,如下程式碼所示:
public class ArgumentExample { public static void main(String[] args) { method(“Java”); } /** * 固定引數方法 */ public static void method(String name) { System。out。println(“固定引數:” + name); }}
可選引數注意事項
可選引數在使用時要注意以下 4 個問題。
1。可選引數是從0到無窮
可選引數的呼叫個數是從 0 到無窮,而不是從 1 到無窮,這點需要注意一下,如以下程式碼所示:
public class ArgumentExample { public static void main(String[] args) { method(); } /** * 可選引數方法 */ public static void method(String。。。 names) { System。out。println(“可選引數數量:” + names。length); }}
以上程式的執行結果如下圖所示:
從上述程式碼可以看出,可選引數即使不傳遞任何引數,也就是 0 個引數,也是能正常呼叫到的。
2。一個方法只能有一個可選引數
一個方法中只能有一個可選引數,如果有多個可選引數程式會報錯,如下圖所示:
3。可選引數必須要放在方法最後
可選引數如果不放在方法引數的最後面,那麼編譯器也會報錯,如下圖所示:
4。可選引數和其他同名方法組成方法過載
可選引數和其他的同名方法可以並存,並且它們組成了方法過載,如下程式碼所示:
優先呼叫固定引數還是可選引數?
基本知識點介紹完,接下來咱們回到本文的主題,當一個方法中有兩類引數:固定引數和可選引數時,究竟是先呼叫固定引數呢?還是先呼叫可選引數呢?
接下來咱們使用一段程式碼來測試一下:
public class ArgumentExample { public static void main(String[] args) { method(“磊哥聊程式設計”); } /** * 固定引數方法 */ public static void method(String name) { System。out。println(“呼叫固定引數:” + name); } /** * 可選引數方法 */ public static void method(String。。。 names) { System。out。println(“呼叫可選引數:” + names。length); }}
以上程式的執行結果如下:
結論
從上面的結果可以看出,
當程式中有固定引數和可選引數時,優先呼叫固定引數,而非可選引數
。
原因分析
看到這,可能有朋友已經意識到了,如果你看過我上一篇《為什麼不同返回型別不算方法過載?》就全明白了,究竟是先呼叫可選引數還是固定引數?上一篇文章在介紹方法過載呼叫的優先順序規則裡已經說過了:其中
可選引數的呼叫優先順序是最低的,在固定引數和可選引數之間還有其他的呼叫選項
。因為有些朋友沒注意到,或者沒看到,所以我這裡再簡單的回顧一下。
第1優先順序:精準引數匹配
方法過載會優先呼叫和方法引數型別一模一樣的固定引數方法。
第2優先順序:呼叫基本型別自動轉換成更大的基本型別
如果是基本資料型別,那麼方法過載呼叫的第 2 匹配原則是自動轉換成更大的基本資料型別,如以下程式碼:
public class OverloadExample { public static void main(String[] args) { OverloadExample example = new OverloadExample(); example。method(12); } public void method(long num) { System。out。println(“呼叫 long 方法”); } public void method(Integer num) { System。out。println(“呼叫 Integer 方法”); } public void method(Object num) { System。out。println(“呼叫 Object 方法”); } public void method(int。。。 num) { // 可選引數 System。out。println(“呼叫 int。。。 方法”); }}
以上程式的執行結果如下圖所示:
第3優先順序:自動裝/拆箱匹配
如果存在基本型別對應的包裝型別,或者是包裝型別對應的基本型別的方法過載,那麼會優先呼叫自動裝箱或自動拆箱的方法過載,如以下程式碼所示:
public class OverloadExample { public static void main(String[] args) { OverloadExample example = new OverloadExample(); example。method(12); } public void method(Integer num) { System。out。println(“呼叫 Integer 方法”); } public void method(Object num) { System。out。println(“呼叫 Object 方法”); } public void method(int。。。 num) { // 可選引數 System。out。println(“呼叫 int。。。 方法”); }}
以上程式的執行結果如下圖所示:
第4優先順序:按照繼承路線依次向上匹配父類
當有父類引數時會優先呼叫父類過載方法,如下程式碼所示:
public class OverloadExample { public static void main(String[] args) { OverloadExample example = new OverloadExample(); example。method(12); } public void method(Object num) { System。out。println(“呼叫 Object 方法”); } public void method(int。。。 num) { // 可選引數 System。out。println(“呼叫 int。。。 方法”); }}
以上程式的執行結果如下圖所示:
第5優先順序:可選引數匹配
可選引數的呼叫優先順序是最低的,當一個類中只有可選引數方法時,才會呼叫可選引數方法。
總結
可選引數是 JDK 5 中新增的以“。。。”格式存在的引數型別,可選引數可以匹配 0 到無窮個引數,但一個方法中只能有一個可選引數,且可選引數要放在方法引數的最後面。它可以和固定引數組成方法過載,但可選引數的呼叫優先順序是最低的。
是非審之於己,譭譽聽之於人,得失安之於數。