首頁 >Java >java教程 >使用Java中可變長參數的實例

使用Java中可變長參數的實例

零下一度
零下一度原創
2018-05-29 09:20:531634瀏覽

在Java5 中提供了變長參數(varargs),也就是在方法定義中可以使用個數不確定的參數,對於同一方法可以使用不同個數的參數調用,例如print("hello"); print("hello","lisi");print("hello","張三", "alexia");下面介紹如何定義可變長參數以及如何使用可變長參數。

1. 可變長參數的定義

使用...表示可變長參數,例如

print(String... args){
   ...
}

在具有可變長參數的方法中可以把參數當成陣列使用,例如可以循環輸出所有的參數值。

print(String... args){
   for(String temp:args)
      System.out.println(temp);
}

2. 可變長參數的方法的呼叫

呼叫的時候可以給任多個參數也可不給參數,例如:

print();
print("hello");
print("hello","lisi");
print("hello","张三", "alexia")

3. 可變長參數的使用規則

3.1 在呼叫方法的時候,如果能夠和固定參數的方法匹配,也能夠與可變長參數的方法匹配,則選擇固定參數的方法。看下面程式碼的輸出:

package com;

// 这里使用了静态导入
import static java.lang.System.out;

public class VarArgsTest {

    public void print(String... args) {
        for (int i = 0; i < args.length; i++) {
            out.println(args[i]);
        }
    }

    public void print(String test) {
        out.println("----------");
    }

    public static void main(String[] args) {
        VarArgsTest test = new VarArgsTest();
        test.print("hello");
        test.print("hello", "alexia");
    }
}

3.2 如果要呼叫的方法可以和兩個可變參數匹配,則出現錯誤,例如下面的程式碼:

package com;

// 这里使用了静态导入
import static java.lang.System.out;

public class VarArgsTest1 {

    public void print(String... args) {
        for (int i = 0; i < args.length; i++) {
            out.println(args[i]);
        }
    }

    public void print(String test,String...args ){
          out.println("----------");
    }

    public static void main(String[] args) {
        VarArgsTest1 test = new VarArgsTest1();
        test.print("hello");
        test.print("hello", "alexia");
    }
}

對於上面的程式碼,main方法中的兩個調用都不能編譯通過,因為編譯器不知道該選哪個方法調用,如下所示:

3.3 一個方法只能有一個可變長參數,並且這個可變長參數必須是該方法的最後一個參數

以下兩種方法定義都是錯誤的。

 public void test(String... strings,ArrayList list){
  
 }
 
 public void test(String... strings,ArrayList... list){
  
 }

4. 可變長參數的使用規格

4.1 避免具有可變長參數的方法重載:如3.1中,編譯器雖然知道怎麼調用,但人容易陷入調用的陷阱及誤區

4.2 別讓null值和空值威脅到變長方法,如3.2中所示,為了說明null值的調用,重新給一個例子:

package com;public class VarArgsTest1 {

    public void print(String test, Integer... is) {
        
    }

    public void print(String test,String...args ){
          
    }

    public static void main(String[] args) {
        VarArgsTest1 test = new VarArgsTest1();
        test.print("hello");
        test.print("hello", null);
    }
}

這時會發現兩個呼叫編譯都不通過:

因為兩個方法都匹配,編譯器不知道選哪個,於是報錯了,這裡同時還有一個非常不好的編碼習慣,即調用者隱藏了實參類型,這是非常危險的,不僅僅調用者需要「猜測」該調用哪個方法,而且被調用者也可能產生內部邏輯混亂的情況。對於本例來說應該做如下修改:

    public static void main(String[] args) {
        VarArgsTest1 test = new VarArgsTest1();
        String[] strs = null;
        test.print("hello", strs);
    }

4.3 覆寫變長方法也要循規蹈矩

下面看一個例子,大家猜測下程式能不能編譯通過:

package com;

public class VarArgsTest2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        // 向上转型
        Base base = new Sub();
        base.print("hello");
        
        // 不转型
        Sub sub = new Sub();
        sub.print("hello");
    }

}

// 基类
class Base {
    void print(String... args) {
        System.out.println("Base......test");
    }
}

// 子类,覆写父类方法
class Sub extends Base {
    @Override
    void print(String[] args) {
        System.out.println("Sub......test");
    }
}

答案當然是編譯不通過,是不是覺得很奇怪?

 第一個能編譯通過,這是為什麼?事實上,base物件把子類別物件sub做了向上轉型,形參列表是由父類別決定的,當然可以通過。而看看子類別直接呼叫的情況,這時編譯器看到子類別覆寫了父類別的print方法,因此肯定使用子類別重新定義的print方法,儘管參數列表不匹配也不會跑到父類再去匹配下,因為找到了就不再找了,因此有了類型不匹配的錯誤。

這是個特例,覆寫的方法參數清單竟然可以與父類別不相同,這違反了覆寫的定義,並且會引發莫名其妙的錯誤。

這裡,總結下覆寫必須滿足的條件:

(1)重寫方法不能縮小存取權限;

(2)參數清單必須與被重寫方法相同(包括顯示形式);

(3)返回類型必須與被重寫方法的相同或是其子類別;

(4)重寫方法不能拋出新的異常,或超過了父類範圍的異常,但是可以拋出更少、更有限的異常,或者不拋出異常。

最後,給一個有陷阱的例子,大家應該要知道輸出結果:

package com;

public class VarArgsTest {
    public static void m1(String s, String... ss) {
        for (int i = 0; i < ss.length; i++) {
            System.out.println(ss[i]);
        }
    }

    public static void main(String[] args) {

        m1("");
        m1("aaa");
        m1("aaa", "bbb");
    }
}

以上是使用Java中可變長參數的實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn