Java での可変長パラメーターの使用例

零下一度
リリース: 2018-05-29 09:20:53
オリジナル
1578 人が閲覧しました

Java5 では変数パラメーター (varargs) が提供されています。つまり、メソッド定義では不確実な数のパラメーターを使用でき、print("hello") のように同じメソッドを異なる数のパラメーターで呼び出すことができます。 print( "hello","lisi");print("hello","Zhang San", "alexia");次に、可変長パラメーターの定義方法と可変長パラメーターの使用方法について説明します。

1. 可変長パラメータの定義

Use... を使用して、

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 呼び出されるメソッドが 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");
    }
}
ログイン後にコピー

上記のコードでは、2 つの呼び出しのどちらも以下に示すように、コンパイラはどのメソッドを呼び出すべきかわからないため、コンパイルは成功します:

3.3 メソッドは可変長パラメータを 1 つだけ持つことができ、この可変長パラメータはメソッドの最後のパラメータである必要があります。

以下の2つ どちらのメソッド定義も間違っています。 4. 可変長パラメータの使用仕様

4.1 可変長パラメータによるメソッドのオーバーロードを避ける: 3.1 と同様、コンパイラは呼び出し方法を知っていますが、人々は呼び出しの罠や誤解に簡単に陥る可能性があります

4.2 null 値を許可しない3.2 に示すように、null 値は可変長メソッドの脅威となります。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");
    }
}
ログイン後にコピー

答えはもちろん、コンパイルが通るかどうかです。それは奇妙だと思いませんか?

最初のものはコンパイルして渡すことができます。これはなぜですか?実際、基本オブジェクトはサブクラス オブジェクト 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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート