Java

変数引数

Language の目次


これまでのリリースでは、任意の個数の値を取るメソッドでは、そのメソッドの呼び出し前に、配列を作成して値を代入する必要がありました。たとえば、MessageFormat クラスを使用してメッセージをフォーマットする例を示します。
Object[] arguments = {
    new Integer(7),
    new Date(),
    "a disturbance in the Force"
};

String result = MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet "
     + "{0,number,integer}.", arguments);

複数の引数を配列で渡す必要があることは変わりありませんが、変数引数機能によって自動的に処理が行われ、ユーザからは隠されます。さらに、既存の API との上位互換性があります。そのため、たとえば MessageFormat.format メソッドに、次の宣言が追加されました。

    public static String format(String pattern,
                                Object... arguments);

最後の引数の型の後に続く 3 つのピリオドは、最後の引数が配列、または一連の引数として渡されることを示しています。変数引数は、最後の引数の位置でだけ使用できます。MessageFormat.format の新しい変数引数宣言では、上記の呼び出しは、次のように短くわかりやすい呼び出しに置き換えることができます。

String result = MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet "
    + "{0,number,integer}.",
    7, new Date(), "a disturbance in the Force");

オートボクシング機能と変数引数との間には、強い相乗効果があります。リフレクションを使用した次のプログラムに、相乗効果の例を示します。

// Simple test framework
public class Test {
    public static void main(String[] args) {
        int passed = 0;
        int failed = 0;
        for (String className : args) {
            try {
                Class c = Class.forName(className);
                c.getMethod("test").invoke(c.newInstance());
                passed++;
            } catch (Exception ex) {
                System.out.printf("%s failed: %s%n", className, ex);
                failed++;
            }
        }
        System.out.printf("passed=%d; failed=%d%n", passed, failed);
    }
}

この短いプログラムは、完全に動作する、最小限のテストフレームワークです。コマンド行で、クラス名のリストを取ります。プログラムは、クラス名ごとにパラメータのないコンストラクタを使用してクラスをインスタンス化し、test というパラメータのないメソッドを呼び出します。インスタンス化、または呼び出しで例外をスローした場合、test は失敗したと見なされます。障害は出力され、その後に test の結果の概要が続きます。リフレクトによるインスタンス化および呼び出しのために、明示的に配列を作成する必要はなくなりました。getMethod メソッドと invoke メソッドは、変数引数のリストを受け入れることができます。またこのプログラムでは、変数引数を利用する新しい printf の機能を使用しています。変数引数を使用しない場合と比べて、プログラムは非常に読みやすくなります。

変数引数を使用するケースは、顧客側からすると、API で変数引数を使用できるときは、必ず利用するべきです。コア API で使用する重要な場合としては、リフレクト、メッセージ書式指定、新しい printf 機能などがあります。API 設計者側からすると、変数引数は、利点がはっきりしている場合にだけ、慎重に使用するべきです。一般的に、変数引数を使用するメソッドはオーバーロードしないようにします。オーバーロードすると、プログラマにとっては、どのオーバーロードが呼び出されたのかわかりにくくなるからです。


Copyright © 2004 Sun Microsystems, Inc.All Rights Reserved.

コメントや提案をお寄せください。

Sun

Java ソフトウェア