Javaコラム Javaエンジニアのためのお役立ちコラム

Javaの可変引数とは?可変引数のルール・可変引数に似た機能のオーバーロード

 
Javaの可変引数とは?可変引数のルール・可変引数に似た機能のオーバーロード
SE
Javaの可変引数とはどのようなものなのでしょうか。
PM
メソッドのパラメータを好きなだけ設定できるという機能です。

Javaの可変引数とは?


Javaの可変引数とは、メソッドのパラメータを好きなだけ設定できるという機能です。言葉ではわかりにくいので、実例で説明しましょう。以下が可変引数の使用例です。

実行結果は以下になります。


いう
えお
かき
くけ

型名の後に…で可変引数になる

上のJavaサンプルのように、

メソッド名(型名… 配列変数名)

とすると、パラメータをいくつでも自由に指定することが可能になります。なお可変引数はメソッドの中では配列として扱われますが、これは以下のように配列をパラメータで渡すのに似た機能と言えます。

この実行結果は以下になります。

あい
うえ

可変引数のルール

Javaの可変引数にはいくつかルールがあります。まず可変引数は1つのメソッドに1つだけで、かつ可変引数は単独であるか、最後のパラメータでなければなりません。

可変引数に似た機能のオーバーロードとは?

Javaには可変引数に似た機能でオーバーロードがあります。オーバーロードとは以下のように、同じ名前でパラメータが違うメソッドを可能にする機能です。

実行結果は以下になります。

あいうえお
かき くけこ

オーバーロードと可変引数が混在したら?

もし上のサンプルに可変引数のメソッドを追加したらどうなるのでしょうか?呼び出す側はオーバーロードなのか可変引数なのか区別がつかなくなるように思えるでしょう。どうなるかを確認するために、上のJavaサンプルを以下のように直してみます。

可変引数よりオーバーロードの方が優先される

上のJavaサンプルの実行結果は以下になります。

あいうえお
かき くけこ
さ 可変引数
し 可変引数
すせそ 可変引数

つまり、メソッドを呼び出す時にオーバーロードの方に該当する場合はオーバーロードのメソッドが呼ばれ、それ以外の場合は可変引数のメソッドが呼ばれるということです。可変引数よりオーバーロードの方が優先度が高いということです。

可変引数は配列のパラメータとは共存不可

可変引数よりオーバーロードが優先されると言いましたが、例外があります。上のJavaサンプルに、以下のメソッドを追加してみましょう。

結果はDuplicate methodという重複エラーになります。配列のパラメータのメソッドを追加しても、その場合は呼び出し側が配列を渡すため区別ができるので問題は無さそうに感じます。

しかし可変引数はJavaの内部では配列として扱われるので、配列のパラメータを持つメソッドと共存することはできません。そのため見た目は重複していないのに重複エラーになるということです。

可変引数が配列扱いのために生じる落とし穴

上で言ったように可変引数は配列として扱われますが、そのせいで可変引数に「配列」を渡した時に意外な動作をする時があります。以下のJavaサンプルを実行してみましょう。

可変引数は配列に変換したりしなかったりする

上のJavaサンプルは渡されたパラメータの配列としてのサイズを表示します。実行結果は以下になります。

3
3
2
1

この結果は意外に感じるでしょう。最初の3は”あ”, “い”, “う”を渡した時で、この結果の3はわかります。次の3はnew String[]{“あ”, “い”, “う”}を渡した結果ですが、配列でも1つのデータなので1の方が正しい気もするでしょう。

ところが可変引数は配列を丸ごと渡されて、それが可変引数の型として扱える場合は、そのまま配列として扱ってしまいます。これは意外に感じる動作のため、注意喚起のワーニングが出ます。

可変引数に配列を渡すと混乱しやすい

しかし次のnew String[]{“あ”, “い”, “う”}, “え”を渡した時の結果、これは2になります。上の結果からすると4が正しいように思えますが、複数のパラメータがある場合は1つ目の配列を1つのデータとして扱うため、わかりにくいです。

そして最後のnew int[] {0, 1, 2}を渡した時ですが、これは1です。3が正しいように思えますが、int型はObject型にできないので、この配列は1つのデータという扱いになって3になります。とてもわかりにくい動作です。

SE
Java可変引数を積極的に使用しない方が良いのは知らなかったです。
PM
Javaで可変引数を使用する際はこの記事を参考にしてみてください。

Javaの可変引数の動作に注意しよう

Java可変引数について解説しましたが、ご理解頂けましたでしょうか。可変引数とオーバーロードの競合や、可変引数に配列を渡した時のわかりにくい動作から、積極的に使用しない方が良い機能と言えます。

可変引数はC言語などの古くから存在する言語にあった機能のため、互換性の観点から追加された可能性があります。どうしても必要と感じた時以外は使用を避けた方がいいでしょう。


Javaでのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)

Search

Popular

recommended

Categories

Tags