更新時(shí)間:2020-06-01 16:30:48 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2543次
在Java5中提供了變長(zhǎng)參數(shù)(varargs),也就是在方法定義中可以使用個(gè)數(shù)不確定的參數(shù),對(duì)于同一方法可以使用不同個(gè)數(shù)的參數(shù)調(diào)用,例如print("hello");print("hello","lisi");print("hello","張三","alexia");下面介紹如何定義可變長(zhǎng)參數(shù)以及如何使用可變長(zhǎng)參數(shù)。

1.可變長(zhǎng)參數(shù)的定義
使用...表示可變長(zhǎng)參數(shù),例如
print(String...?args){
??...
}
在具有可變長(zhǎng)參數(shù)的方法中可以把參數(shù)當(dāng)成數(shù)組使用,例如可以循環(huán)輸出所有的參數(shù)值。
print(String...?args){
???for(String?temp:args)
??????System.out.println(temp);
}
2.可變長(zhǎng)參數(shù)的方法的調(diào)用
調(diào)用的時(shí)候可以給出任意多個(gè)參數(shù)也可不給參數(shù),例如:
print();
print("hello");
print("hello","lisi");
print("hello","張三",?"alexia")
3.可變長(zhǎng)參數(shù)的使用規(guī)則
(1)在調(diào)用方法的時(shí)候,如果能夠和固定參數(shù)的方法匹配,也能夠與可變長(zhǎng)參數(shù)的方法匹配,則選擇固定參數(shù)的方法??聪旅娲a的輸出:
package?com;
//?這里使用了靜態(tài)導(dǎo)入
import?static?java.lang.System.out;
public?class?VarArgsTest?{
????public?void?print(String...?args)?{
????????for?(int?i?=?0;?i?<?args.length;?i++)?{
????????????out.println(args[i]);
????????}
????}
????public?void?print(String?test)?{
????????out.println("----------");
????}
????public?static?void?main(String[]?args)?{
????????VarArgsTest?test?=?new?VarArgsTest();
????????test.print("hello");
????????test.print("hello",?"alexia");
????}
}
(2)如果要調(diào)用的方法可以和兩個(gè)可變參數(shù)匹配,則出現(xiàn)錯(cuò)誤,例如下面的代碼:
package?com;
//?這里使用了靜態(tài)導(dǎo)入
import?static?java.lang.System.out;
public?class?VarArgsTest1?{
????public?void?print(String...?args)?{
????????for?(int?i?=?0;?i?<?args.length;?i++)?{
????????????out.println(args[i]);
????????}
????}
????public?void?print(String?test,String...args?){
??????????out.println("----------");
????}
????public?static?void?main(String[]?args)?{
????????VarArgsTest1?test?=?new?VarArgsTest1();
????????test.print("hello");
????????test.print("hello",?"alexia");
????}
}
對(duì)于上面的代碼,main方法中的兩個(gè)調(diào)用都不能編譯通過(guò),因?yàn)榫幾g器不知道該選哪個(gè)方法調(diào)用,如下所示:

(3)一個(gè)方法只能有一個(gè)可變長(zhǎng)參數(shù),并且這個(gè)可變長(zhǎng)參數(shù)必須是該方法的最后一個(gè)參數(shù)
以下兩種方法定義都是錯(cuò)誤的。
public void test(String...strings,ArrayList list){
}
public void test(String...strings,ArrayList...list){
}
4.可變長(zhǎng)參數(shù)的使用規(guī)范
(1)避免帶有可變長(zhǎng)參數(shù)的方法重載:如3.1中,編譯器雖然知道怎么調(diào)用,但人容易陷入調(diào)用的陷阱及誤區(qū)
(2)別讓null值和空值威脅到變長(zhǎng)方法,如3.2中所示,為了說(shuō)明null值的調(diào)用,重新給出一個(gè)例子:
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);
????}
}

因?yàn)閮蓚€(gè)方法都匹配,編譯器不知道選哪個(gè),于是報(bào)錯(cuò)了,這里同時(shí)還有個(gè)非常不好的編碼習(xí)慣,即調(diào)用者隱藏了實(shí)參類型,這是非常危險(xiǎn)的,不僅僅調(diào)用者需要“猜測(cè)”該調(diào)用哪個(gè)方法,而且被調(diào)用者也可能產(chǎn)生內(nèi)部邏輯混亂的情況。對(duì)于本例來(lái)說(shuō)應(yīng)該做如下修改:
public?static?void?main(String[]?args)?{
????VarArgsTest1?test?=?new?VarArgsTest1();
????String[]?strs?=?null;
?????test.print("hello",?strs);
?}
(3)覆寫變長(zhǎng)方法也要循規(guī)蹈矩
下面看一個(gè)例子,大家猜測(cè)下程序能不能編譯通過(guò):
package?com;
public?class?VarArgsTest2?{
????/**
?????*?@param?args
?????*/
????public?static?void?main(String[]?args)?{
????????//?TODO?Auto-generated?method?stub
????????//?向上轉(zhuǎn)型
????????Base?base?=?new?Sub();
????????base.print("hello");
????????
????????//?不轉(zhuǎn)型
????????Sub?sub?=?new?Sub();
????????sub.print("hello");
????}
}
//?基類
class?Base?{
????void?print(String...?args)?{
????????System.out.println("Base......test");
????}
}
//?子類,覆寫父類方法
class?Sub?extends?Base?{
????@Override
????void?print(String[]?args)?{
????????System.out.println("Sub......test");
????}
}
答案當(dāng)然是編譯不通過(guò),是不是覺(jué)得很奇怪?

第一個(gè)能編譯通過(guò),這是為什么呢?事實(shí)上,base對(duì)象把子類對(duì)象sub做了向上轉(zhuǎn)型,形參列表是由父類決定的,當(dāng)然能通過(guò)。而看看子類直接調(diào)用的情況,這時(shí)編譯器看到子類覆寫了父類的print方法,因此肯定使用子類重新定義的print方法,盡管參數(shù)列表不匹配也不會(huì)跑到父類再去匹配下,因?yàn)檎业搅司筒辉僬伊耍虼擞辛祟愋筒黄ヅ涞腻e(cuò)誤。
這是個(gè)特例,覆寫的方法參數(shù)列表竟然可以與父類不相同,這違背了覆寫的定義,并且會(huì)引發(fā)莫名其妙的錯(cuò)誤。
這里,總結(jié)下覆寫必須滿足的條件:
最后,給出一個(gè)有陷阱的例子,大家應(yīng)該知道輸出結(jié)果:
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");
????}
}
以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Javaweb系統(tǒng)視頻之架構(gòu)演變”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)