Java語(yǔ)言在JDK1.5中推出可變參數(shù),variable arguments,或簡(jiǎn)稱varargs。這一新語(yǔ)言特征給軟件開(kāi)發(fā)人員在編寫(xiě)方法重載時(shí)提供了方便和靈活性。但可變參數(shù)的應(yīng)用并不像想象的那么簡(jiǎn)單,使用時(shí)有其特殊要求和局限性。
12.7.1 重載的例子
讀者朋友可能有這樣的編程經(jīng)歷:在編寫(xiě)一個(gè)方法時(shí),其參數(shù)隨著程序運(yùn)行的條件而變化,在編譯期間無(wú)法確定。具體地講,例如編寫(xiě)一個(gè)打印參加聚會(huì)party的程序,其中方法printInvitation()將根據(jù)作為參數(shù)的參加人姓名,打印邀請(qǐng)卡。但這個(gè)參數(shù)的數(shù)量事先并不確定。當(dāng)然可以編寫(xiě)許多重載的方法來(lái)解決這個(gè)問(wèn)題,如:
void printInvitation(String name);void printInvitation(String name1, String name2);
void printInvitation(String name1, String name2, String name3);
...
問(wèn)題是編寫(xiě)多少個(gè)重載的方法才可以解決給所有參加者打印邀請(qǐng)卡?也許需要改變您的程序設(shè)計(jì),而使用數(shù)組或者鏈接表了。
應(yīng)用可變參數(shù)可以方便、靈活地解決這類問(wèn)題。例如:
//完整程序存在本書(shū)配套資源目錄Ch12名為VarargsTest.javavoid printInvitation(String...names) {
for (String name : names) {
makeCard(name); //調(diào)用方法按照姓名打印邀請(qǐng)卡
System.out.println("Recording info: invitation card has been printed for " + name);
}
}
這里,(String...names)便是可變參數(shù)。它包括從0到任意個(gè)相同類型的參數(shù)。在編譯期間,這個(gè)可變參數(shù)將被轉(zhuǎn)換為字符串?dāng)?shù)組形式,即:
void printInvitation(String[] names)
如下是調(diào)用這個(gè)方法的例子:
printInvitation("李剛", "David Smith");printInvitation("Greg Wu", "Paul Nguyen", "Liu Wei", "張新");
printInvitation(); //無(wú)參數(shù)
當(dāng)在無(wú)參數(shù)情況下調(diào)用這個(gè)方法時(shí),將不執(zhí)行任何這個(gè)方法中的代碼。
如下是運(yùn)行結(jié)果:
Recording info: invitation card has been printed for 李剛Recording info: invitation card has been printed for David Smith
Recording info: invitation card has been printed for Greg Wu
Recording info: invitation card has been printed for Paul Nguyen
Recording info: invitation card has been printed for Liu Wei
Recording info: invitation card has been printed for 張新
12.7.2 怎樣工作
可變參數(shù)也不神秘。實(shí)際上,JVM將根據(jù)程序中調(diào)用這個(gè)方法時(shí)提供的參數(shù)數(shù)量,來(lái)裝載和運(yùn)行它。
可變參數(shù)的簡(jiǎn)單語(yǔ)法格式為:
methodName([argumentList], dataType...argumentName);
其中:
argumentList——普通參數(shù),可選項(xiàng)。
dataType——數(shù)據(jù)類型或者類。自動(dòng)轉(zhuǎn)換成dataType代表的數(shù)組。
...——Java的操作符。表示0到多個(gè)。必須是3個(gè)點(diǎn)。
argumentName——參數(shù)名。
注意,可變參數(shù)必須在。
下面是應(yīng)用可變參數(shù)的更多例子:
// 完整程序存在本書(shū)配套資源目錄Ch12名為VarargsTest.javapublic static int sumInts(int...numbers) { //可變整數(shù)數(shù)組類型參數(shù)
int sum = 0;
for (int num : numbers)
sum +=num;
return sum;
}
再如:
public void totalTax(String name, double rate, double...amount) {//普通參數(shù)在前、可變參數(shù)在后
double total = 0.0,
tax = 0.0;
for (double amount : amounts)
total += amount;
tax = total * rate;
System.out.println("Name: " + name + "nTotal: " + total + "ntax: " + tax);
}
可變參數(shù)也可應(yīng)用在構(gòu)造器中。例如:
public class Supper {public Supper(char...characters) {
...
}
在子類中,可以覆蓋這個(gè)構(gòu)造器,如:
class SubClass extends Supper {public SubClass(char...characters) {
...
}
}
但無(wú)法在子類中調(diào)用超類的這個(gè)構(gòu)造器。
更多信息 可變參數(shù)可以用在構(gòu)造器中,并可以覆蓋。
12.7.3 可變參數(shù)方法重載
可以對(duì)具有可變參數(shù)的方法重載。如下例子:
void someMethod(int count, double...prices) {//語(yǔ)句體
...
}
void someMethod(double...prices) { //重載
//語(yǔ)句體
...
}
double someMethod(String...names) { //重載
//語(yǔ)句體
...
}
...
對(duì)方法someMethod()實(shí)行重載。對(duì)具有可變參數(shù)的方法重載遵循一般方法重載原則。
12.7.4 應(yīng)用實(shí)例
如下程序應(yīng)用枚舉和可變參數(shù),對(duì)在12.4.4討論過(guò)的根據(jù)用戶要求打印跑車信息的程序進(jìn)一步修改,使之具有更強(qiáng)功能。首先,在程序中加入了如下兩個(gè)用來(lái)處理跑車顏色和付款方式的枚舉類型對(duì)象:
//完整程序存在本書(shū)配套資源目錄Ch12名為VarargsApp.javaenum ColorType {
WHITE {String getDescription(){
return "有淺白、暗白、和亮白可選";
}
},
SILVER {String getDescription() {
return "有銀白、銀灰、純銀色可選";
}
},
BLACK {String getDescription() {
return "有深黑和淺黑可選";
}
};
abstract String getDescription();
}
enum PaymentType {
CASH("有10%特別優(yōu)惠"),
CREDIT("接受所有信用卡"),
LOAN("貸款利息為.56%");
final private String payment;
private PaymentType(String payment) {
this. payment = payment;
}
public String getPayment() {
return payment;
}
}
另外,在SportCar中,根據(jù)用戶的選擇,加入了對(duì)跑車類型、顏色,以及付款方式的處理方法,并且利用可變參數(shù)。例如:
class SportCar {SportCarType type; //創(chuàng)建
ColorType color;
PaymentType payment;
public SportCar (String...choices) { //可變參數(shù)
type = null; //初始化
color = null;
payment = null;
processInfo(choices); //調(diào)用處理信息方法
}
private void processInfo(String[] choices) {
if (choices.length == 1) { //處理跑車類型
processType(choices[0]);
}
else if (choices.length == 2) { //處理跑車類型和顏色
processType(choices[0]);
processColor(choices[1]);
}
else if (choices.length == 3) { //處理跑車類型、顏色和付款方式
processType(choices[0]);
processColor(choices[1]);
processPayment(choices[2]);
}
}
private void processType(String type) { //處理類型
if (type.equals("P"))
this.type = SportCarType.PORSCHE;
else if (type.equals("F"))
this.type = SportCarType.FERRARI;
else if(type.equals("J"))
this.type = SportCarType.JAGUAR;
}
...
這個(gè)類的驅(qū)動(dòng)程序如下:
public class VarargsApp {public static void main( String args[] ) {
SportCar yourCar = new SportCar("P"); //創(chuàng)建一個(gè)參數(shù)的對(duì)象
System.out.println("你要的跑車信息:n" + yourCar + "n");
SportCar myCar = new SportCar("J", "S"); //創(chuàng)建兩個(gè)參數(shù)的對(duì)象
System.out.println("我要的跑車信息:n" + myCar + "n");
SportCar herCar = new SportCar("F", "B", "C");//創(chuàng)建三個(gè)參數(shù)的對(duì)象
System.out.println("她要的跑車信息:n" + herCar + "n");
}
}
運(yùn)行結(jié)果如下:
你要的跑車信息:制造國(guó):德國(guó)
價(jià)格:$120,000.00
我要的跑車信息:
制造國(guó):英國(guó)
價(jià)格:$110,000.00
有銀白、銀灰、純銀色可選
她要的跑車信息:
制造國(guó): 意大利
價(jià)格:$150,000.00
有深黑和淺黑可選
有10%特別優(yōu)惠
想要了解更多的java技術(shù)那就加入我們吧!