java可變引數運用
阿新 • • 發佈:2019-02-16
可變引數
Java 語言在 JDK1.5 中首次推出可變引數, variable arguments ,或簡稱 varargs 。這一新語言特徵給軟體開發人員在編寫方法過載時提供了方便和靈活性。但可變引數的應用並不像想象的那麼簡單,使用時有其特殊要求和侷限性。
可變引數也不神祕。實際上, JVM 將根據程式中呼叫這個方法時提供的引數數量,來裝載和執行它。
可變引數的簡單語法格式為:
methodName([argumentList], dataType...argumentName);
其中:
argumentList ——普通引數,可選項。
dataType ——資料型別或者類。自動轉換成 dataType 代表的陣列。
... —— Java 的操作符。表示 0 到多個。必須是 3 個點。
argumentName ——引數名。
注意,可變引數必須在最後。
下面是應用可變引數的更多例子:
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) { ... } } 但無法在子類中呼叫超類的這個構造器。 更多資訊 可變引數可以用在構造器中,並可以覆蓋。
可以對具有可變引數的方法過載。如下例子:
void someMethod(int count, double...prices) {
// 語句體
...
}
void someMethod(double...prices) { // 過載
// 語句體
...
}
double someMethod(String...names) { // 過載
// 語句體
...
}
...
對方法someMethod()實行過載。對具有可變引數的方法過載遵循一般方法過載原則。
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%特別優惠
12.7.1 過載的最好例子
讀者朋友可能有這樣的程式設計經歷:在編寫一個方法時,其引數隨著程式執行的條件而變化,在編譯期間無法確定。具體地講,例如編寫一個列印參加聚會 party 的程式,其中方法 printInvitation() 將根據作為引數的參加人姓名,列印邀請卡。但這個引數的數量事先並不確定。當然可以編寫許多過載的方法來解決這個問題,如: void printInvitation(String name); void printInvitation(String name1, String name2); void printInvitation(String name1, String name2, String name3); ... 問題是編寫多少個過載的方法才可以解決給所有參加者列印邀請卡?也許需要改變您的程式設計,而使用陣列或者連結表了。 應用可變引數可以方便、靈活地解決這類問題。例如: 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 怎樣工作
// 普通引數在前、可變引數在後 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 可變引數方法過載
對方法someMethod()實行過載。對具有可變引數的方法過載遵循一般方法過載原則。
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%特別優惠