1. 程式人生 > >如何應用Java的可變引數

如何應用Java的可變引數

Java可變引數

Java語言在JDK1.5中首次推出Java可變引數,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 張新

怎樣工作

       Java可變引數也不神祕。實際上,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); }        Java可變引數也可應用在構造器中。例如: public class Supper {     public Supper(char...characters) {     ...     }        在子類中,可以覆蓋這個構造器,如: class SubClass extends Supper {     public SubClass(char...characters) {         ...     } }        但無法在子類中呼叫超類的這個構造器。       更多資訊  可變引數可以用在構造器中,並可以覆蓋。

Java可變引數方法過載

       可以對具有可變引數的方法過載。如下例子: void someMethod(int count, double...prices) {     //語句體     ...     } void someMethod(double...prices) {              //過載     //語句體     ...     } double someMethod(String...names) {             //過載     //語句體     ... } ...        對方法someMethod()實行過載。對具有可變引數的方法過載遵循一般方法過載原則。        如下程式應用列舉和可變引數,對在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%特別優惠