【Java】可変長引数を解説!Varargsメソッドも分かり易いサンプルコード付き!
この記事では、サンプルコードを使用してJavaの可変引数について学びます。可変引数を使用する場合と使用しない場合についても学習します。
目次
Javaの可変引数とは何か?
Javaメソッドを作成しているとしましょう。ですが、メソッドが受け入れる引数の数はわかりません。この問題に対処するために、Java 1.5では可変引数が導入されました。
Javaでは、メソッドの引数は任意の数を設定する事ができます。可変数の値を受け入れることができる引数のことを可変引数と呼びます。
可変引数を実装する構文は下記のとおりです。
1 2 3 |
accessModifier methodName(datatype…arg){ //メソッド本体 } |
可変引数を定義するには、メソッドの仮パラメーターで… (3つのドット)を使用します。
可変数の引数を受け取るメソッドは、varargsメソッドと呼ばれます。
最初に可変引数を使用しない例を見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class FlyTech { public int flyTechNumber(int a, int b){ return a+b; } public int flyTechNumber(int a, int b, int c){ return a+b+c; } public static void main( String[] args ) { FlyTech obj = new FlyTech(); System.out.println(obj.flyTechNumber(1, 2)); System.out.println(obj.flyTechNumber(1, 2, 3)); } } |
出力結果
3
6
上記の例でわかるように、flyTechNumber()メソッドをオーバーロードして3つの引数で機能させる必要がありました。
5つ、10、100を追加したい場合はどうなりますでしょうか?
これは、varargsを使うことで解決できます。
ではコード例を見てみましょう
例:可変引数の操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class VarargExample { public int flyTechNumber(int ... args){ System.out.println("引数の長さ: " + args.length); int sum = 0; for(int x: args){ sum += x; } return sum; } public static void main( String[] args ) { VarargExample ex = new VarargExample(); int sum2 = ex.flyTechNumber(2, 4); System.out.println("sum2 = " + sum2); int sum3 = ex.flyTechNumber(1, 3, 5); System.out.println("sum3 = " + sum3); int sum4 = ex.flyTechNumber(1, 3, 5, 7); System.out.println("sum4 = " + sum4); } } |
出力結果
引数の長さ:2
sum2 = 6
引数の長さ:3
sum3 = 9
引数の長さ:4
sum4 = 16
ここでは、flyTechNumber()メソッドはint渡されたパラメーターの合計を返します(渡された引数の数は関係ありません)。
ご覧のとおり、状況によってはvarargsが非常に役立ちます。
メソッドに渡される引数の数がわかっている場合は、メソッドのオーバーロードを使用しました。
たとえば、flyTechNumber()メソッドが2つまたは3つの引数の合計を計算するためだけに使用されることが確実な場合は、最初の例のようにオーバーロードを使用します。
別の例を見てみましょう。 Javaライブラリで定義されたformat()メソッドは、可変引数を受け付けます。JDKでは、format()メソッドは次のように定義されています。
1 2 3 |
public static String format(Locale l、String format、Object ... args){ // 体 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
例:format()メソッド class Company { public static void main(String[] args) { String siteName = "flytech.work"; int empCount = 6; String type = "フリーランス募集"; System.out.println( String.format( "サイト名 : %s, Emp Count: %d Type: %s", siteName, empCount, type ) ); } } |
出力結果
サイト名:flytech.work、Emp Count:6タイプ:フリーランス募集
varargsが使われるシーン
次のサンプルコードを見てみましょう
1 2 3 |
public int flyTechNumber(int ... nums){ //メソッド本体 } |
…構文はメソッドがゼロ以上の引数で呼び出すことができることをJavaコンパイラに指示します。
結果として、nums変数は暗黙に配列の型int[ ]として宣言されます。そのことにより、メソッド内ではnums 変数は配列構文を使用してアクセスされます。
※引数がない場合、長さ nums は0
Varargsメソッドのオーバーロード
一般的なメソッドと同様に、varargメソッドもオーバーロードする事ができます。
例:Varargsメソッドのオーバーロード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class VarargOverload { private void sample(int ... args){ int sum = 0; for (int i: args) { sum += i; } System.out.println("sum = " + sum); } private void sample(boolean p, String ... args){ boolean negate = !p; System.out.println("negate = " + negate); System.out.println("args.length = "+ args.length); } public static void main( String[] args ) { VarargOverload obj = new VarargOverload(); obj.sample(1, 2, 3); obj.sample(true, "hello", "world"); } } |
出力結果
sum= 6
negate =false
args.length = 2
上記のプログラムでsample()は、受け入れる引数の数を変更することにより、メソッドがオーバーロードされます。
Varargsを使用する際の注意事項
Java の vargarsを使用する際に覚えておくべきことがいくつかあります。
メソッドのシグネチャを定義するときは、可変引数は常に最後に定義する!
可変引数は、メソッドに渡される最後の引数でなければなりません。
例えば、次のdoSomething()ようにメソッドを呼び出したとします。
doSomething(1、2、3、4)
1 2 3 4 |
//不正なメソッド宣言 public void doSomething(int ... nums、int p){ //メソッド本体 } |
上記の例の場合、コンパイラは渡された引数numsの数を把握できません のでエラーになります。
メソッドを次のように定義すると、Javaコンパイラは最初の引数を pと認識し、残りのint引数numsは可変引数と認識して、エラーは解消されます。
1 2 3 |
public void doSomething(int p、int ... nums){ //メソッド本体 } |
メソッドは、varargsパラメーターを1つだけしか持つことができません。
メソッドは、varargsパラメーターを1つだけしか持つことができません。
たとえば、下記の例のメソッド宣言はエラーになります。
1 2 3 |
int somethingFlytech(int p、float ... floatNums、double ... doubleNums){ //コード } |
Varargsメソッドのオーバーロード時のあいまいさに注意!
下記のsample()ようなオーバーロードメソッドを見てみましょう。
1 2 3 4 5 6 7 8 9 10 |
クラスデモ{ static void sample(int ... vargs){ //メソッド本体 } static void sample(int n、int ... vargs){ //メソッド本体 } } |
上記のプログラムではsample()、sample()メソッドがオーバーロードされていて、引数の数が異なる場合でも、メソッドを呼び出そうとするとコンパイラーが混乱します。
コンパイラーは、どのメソッドを呼び出すかを認識できません。
コンパイラはsample(int … vargs)、1つのvarargs引数を使用して呼び出そうとしていると考えます。また、コンパイラーは最初のパラメーターsample(int n, int … vargs)、に渡された引数を空の2番目のパラメーターで呼び出しようとしていると考える場合もあります。
2つの可能性があるため、あいまいさが生じます。このため、varargsメソッドをオーバーロードする時は、引数が違っても同じメソッド名は使えあないようにしましょう。
Ryotin
現役フリーランスエンジニアです。使ってるエージェントはフライテック!得意言語はJava。月収は75万円。SESのフリーランスではこれ以上稼ぐのは厳しそう...とはいってもサラリーマンの時より倍の収入だから家族も喜んでるけどね!