Java中可变长参数的使用及注意事项
在Java5 中提供了變長參數(varargs),也就是在方法定義中可以使用個數不確定的參數,對于同一方法可以使用不同個數的參數調用,例如print("hello");print("hello","lisi");print("hello","張三", "alexia");下面介紹如何定義可變長參數 以及如何使用可變長參數。
1. 可變長參數的定義
使用...表示可變長參數,例如
print(String... args){
?? ...
}
在具有可變長參數的方法中可以把參數當成數組使用,例如可以循環輸出所有的參數值。
print(String... args){
?? for(String temp:args)
????? System.out.println(temp);
}
2. 可變長參數的方法的調用
調用的時候可以給出任意多個參數也可不給參數,例如:
print();
print("hello");
print("hello","lisi");
print("hello","張三", "alexia")
3. 可變長參數的使用規則
3.1 在調用方法的時候,如果能夠和固定參數的方法匹配,也能夠與可變長參數的方法匹配,則選擇固定參數的方法。看下面代碼的輸出:
3.2 如果要調用的方法可以和兩個可變參數匹配,則出現錯誤,例如下面的代碼:
對于上面的代碼,main方法中的兩個調用都不能編譯通過,因為編譯器不知道該選哪個方法調用,如下所示:
3.3 一個方法只能有一個可變長參數,并且這個可變長參數必須是該方法的最后一個參數
以下兩種方法定義都是錯誤的。
?public void test(String... strings,ArrayList list){
??
?}
?
?public void test(String... strings,ArrayList... list){
??
?}
4. 可變長參數的使用規范
4.1 避免帶有可變長參數的方法重載:如3.1中,編譯器雖然知道怎么調用,但人容易陷入調用的陷阱及誤區
4.2 別讓null值和空值威脅到變長方法,如3.2中所示,為了說明null值的調用,重新給出一個例子:
package com;public class VarArgsTest1 {public void print(String test, Integer... is) {}public void print(String test,String...args ){}public static void main(String[] args) {VarArgsTest1 test = new VarArgsTest1();test.print("hello");test.print("hello", null);} }這時會發現兩個調用編譯都不通過:
因為兩個方法都匹配,編譯器不知道選哪個,于是報錯了,這里同時還有個非常不好的編碼習慣,即調用者隱藏了實參類型,這是非常危險的,不僅僅調用者需要“猜測”該調用哪個方法,而且被調用者也可能產生內部邏輯混亂的情況。對于本例來說應該做如下修改:
public static void main(String[] args) {VarArgsTest1 test = new VarArgsTest1();String[] strs = null;test.print("hello", strs);}4.3 覆寫變長方法也要循規蹈矩
下面看一個例子,大家猜測下程序能不能編譯通過:
package com;public class VarArgsTest2 {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stub// 向上轉型Base base = new Sub();base.print("hello");// 不轉型Sub sub = new Sub();sub.print("hello");}}// 基類 class Base {void print(String... args) {System.out.println("Base......test");} }// 子類,覆寫父類方法 class Sub extends Base {@Overridevoid print(String[] args) {System.out.println("Sub......test");} }答案當然是編譯不通過,是不是覺得很奇怪?
?
第一個能編譯通過,這是為什么呢?事實上,base對象把子類對象sub做了向上轉型,形參列表是由父類決定的,當然能通過。而看看子類直接調用的情況,這時編譯器看到子類覆寫了父類的print方法,因此肯定使用子類重新定義的print方法,盡管參數列表不匹配也不會跑到父類再去匹配下,因為找到了就不再找了,因此有了類型不匹配的錯誤。
這是個特例,覆寫的方法參數列表竟然可以與父類不相同,這違背了覆寫的定義,并且會引發莫名其妙的錯誤。
這里,總結下覆寫必須滿足的條件:
(1)重寫方法不能縮小訪問權限;
(2)參數列表必須與被重寫方法相同(包括顯示形式);
(3)返回類型必須與被重寫方法的相同或是其子類;
(4)重寫方法不能拋出新的異常,或者超過了父類范圍的異常,但是可以拋出更少、更有限的異常,或者不拋出異常。
?
最后,給出一個有陷阱的例子,大家應該知道輸出結果:
package com;public class VarArgsTest {public static void m1(String s, String... ss) {for (int i = 0; i < ss.length; i++) {System.out.println(ss[i]);}}public static void main(String[] args) {m1("");m1("aaa");m1("aaa", "bbb");} }from: https://www.cnblogs.com/lanxuezaipiao/p/3190673.html 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的Java中可变长参数的使用及注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最大团问题-分支界限法
- 下一篇: Rust错误处理