可變參數(shù)
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
????? 更多信息
?
可變參數(shù)可以用在構(gòu)造器中,并可以覆蓋。
?
Java
語言在
JDK1.5
中首次推出可變參數(shù),
variable arguments
,或簡稱
varargs
。這一新語言特征給軟件開發(fā)人員在編寫方法重載時提供了方便和靈活性。但可變參數(shù)的應(yīng)用并不像想象的那么簡單,使用時有其特殊要求和局限性。
12.7.1 ? 重載的最好例子
讀者朋友可能有這樣的編程經(jīng)歷:在編寫一個方法時,其參數(shù)隨著程序運行的條件而變化,在編譯期間無法確定。具體地講,例如編寫一個打印參加聚會
party
的程序,其中方法
printInvitation()
將根據(jù)作為參數(shù)的參加人姓名,打印邀請卡。但這個參數(shù)的數(shù)量事先并不確定。當(dāng)然可以編寫許多重載的方法來解決這個問題,如:
void printInvitation(String name);
void printInvitation(String name1, String name2);
void printInvitation(String name1, String name2, String name3);
...
問題是編寫多少個重載的方法才可以解決給所有參加者打印邀請卡?也許需要改變您的程序設(shè)計,而使用數(shù)組或者鏈接表了。
應(yīng)用可變參數(shù)可以方便、靈活地解決這類問題。例如:
?
void printInvitation(String...names) {
??? for (String name : names) {
??????? makeCard(name);???????????? //
調(diào)用方法按照姓名打印邀請卡
??????? System.out.println("Recording info: invitation card has been printed for " + name);
??? }
}
這里,
(String...names)
便是可變參數(shù)。它包括從
0
到任意個相同類型的參數(shù)。在編譯期間,這個可變參數(shù)將被轉(zhuǎn)換為字符串?dāng)?shù)組形式,即:
void printInvitation(String[] names)
如下是調(diào)用這個方法的例子:
printInvitation("
李剛
", "David Smith");
printInvitation("Greg Wu", "Paul Nguyen", "Liu Wei", "
張新
")
;
printInvitation();????????? //
無參數(shù)
當(dāng)在無參數(shù)情況下調(diào)用這個方法時,將不執(zhí)行任何這個方法中的代碼。
如下是運行結(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ù)也不神秘。實際上,
JVM
將根據(jù)程序中調(diào)用這個方法時提供的參數(shù)數(shù)量,來裝載和運行它。
??????
可變參數(shù)的簡單語法格式為:
methodName([argumentList], dataType...argumentName);
??????
其中:
?????? argumentList
——普通參數(shù),可選項。
?????? dataType
——數(shù)據(jù)類型或者類。自動轉(zhuǎn)換成
dataType
代表的數(shù)組。
?????? argumentName
——參數(shù)名。
??????
注意,可變參數(shù)必須在最后。
??????
下面是應(yīng)用可變參數(shù)的更多例子:
?
public 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ù)在后
??????????????????????????????????????????? // 普通參數(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òu)造器,如:
class SubClass extends Supper {
??? public SubClass(char...characters) {
??????? ...
??? }
}
??????
但無法在子類中調(diào)用超類的這個構(gòu)造器。
12.7.3 ? 可變參數(shù)方法重載
??????
可以對具有可變參數(shù)的方法重載。如下例子:
void someMethod(int count, double...prices) {
??? //
語句體
??? ...
??? }
void someMethod(double...prices) {????????????? //
重載
??? //
語句體
??? ...
??? }
double someMethod(String...names) { ??????????? //
重載
??? //
語句體
??? ...
}
...
? 對方法someMethod()實行重載。對具有可變參數(shù)的方法重載遵循一般方法重載原則。
? ? ? ? ? ? ? ? ? ?
? 對方法someMethod()實行重載。對具有可變參數(shù)的方法重載遵循一般方法重載原則。
enum 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ù)用戶的選擇,加入了對跑車類型、顏色,以及付款方式的處理方法,并且利用可變參數(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;
}
...
這個類的驅(qū)動程序如下:
public class VarargsApp {
?? public static void main( String args[] ) {
??? ?SportCar yourCar = new SportCar("P");????????? //創(chuàng)建一個參數(shù)的對象
??? ?System.out.println("你要的跑車信息:\n" + yourCar + "\n");
??? ?SportCar myCar = new SportCar("J", "S");?????? //創(chuàng)建兩個參數(shù)的對象
??? ?System.out.println("我要的跑車信息:\n" + myCar + "\n");
??? ?SportCar herCar = new SportCar("F", "B", "C");//創(chuàng)建三個參數(shù)的對象
??? ?System.out.println("她要的跑車信息:\n" + herCar + "\n");
??? }
}
運行結(jié)果如下:
你要的跑車信息:
制造國:德國
價格:$120,000.00
我要的跑車信息:
制造國:英國
價格:$110,000.00
有銀白、銀灰、純銀色可選
她要的跑車信息:
制造國: 意大利
價格:$150,000.00
有深黑和淺黑可選
有10%特別優(yōu)惠