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