メソッド宣言と可変長引数を理解する
可変長引数は、呼出し時に0個以上の値を並べて渡せる宣言です。メソッド本体では配列として扱います。メソッド宣言の基本に加え、配列を直接渡す場合とnull、オーバーロードとの関係を学びます。
この単元で学ぶこと
- 可変長引数を配列として説明する
- 宣言位置と呼出しの合法性を判定する
- 配列・null・オーバーロードの結果を追う
本文解説
宣言と本体 static int count(int... xs){return xs.length;}のint... xsが可変長引数です。本体ではint[]と同じようにlengthや添字を使えます。count(2,4,6)なら三要素の配列として渡されるので3です。戻り値の型はintで、...は戻り値ではなく引数側に書きます。
0個でも呼べる count()は空のint配列を受け取り0を返します。count(7)は一要素なので1です。空配列とnullは別なので、引数を省略した場合にxsがnullになると考えないようにします。xs[0]を無条件に読む本体なら、0個の呼出しで範囲外例外になります。
配列をそのまま渡す int[] a={2,4};count(a)でも2です。可変長引数を配列型の仮引数として使えるためです。この場合はaが指す配列への参照値がそのまま渡され、本体でxs[0]を書き換えると元の配列にも見えます。毎回必ず配列を複製する仕組みではありません。
固定引数と組み合わせる static int sum(int base,int... xs){for(int x:xs)base+=x;return base;}ではbaseを一つ必ず渡し、その後は0個以上です。sum(10,1,2)は13、sum(10)は10。可変長引数は仮引数リストの最後に一つだけ宣言できます。int... xs,int lastの順は不正です。
配列型との同一性 static void f(int... xs)とstatic void f(int[] xs)は同じクラスへ同時宣言できません。可変長引数もシグネチャ上は配列型として扱われるからです。...の有無だけで二つの独立したメソッドを作ることはできません。
nullの渡し方 count((int[])null)はnull配列を受け取り、lengthの参照でNullPointerExceptionになります。int...には整数要素としてnullを一つ詰めることはできません。String...なら(String)nullを一要素として渡す場合と(String[])nullを配列として渡す場合を区別できます。
通常の引数を先に検討 f(int)とf(int...)があると、f(1)は固定引数のint版を選び、f()やf(1,2)は可変長版を選びます。配列を直接渡すf(new int[]{1})は配列型として可変長宣言へ適用できます。「可変長版は常に最後」と考えるだけでなく、固定個数の配列引数として適用できる段階も確認します。
実行確認 0個、一個、複数、配列直接、null配列を別々に試します。lengthと要素を表示し、引数を並べた場合の配列と直接渡した配列の変更先を比較します。不正な宣言順や同一シグネチャは実行できないため、コンパイル診断を確認して分類します。
図解
重要ポイント
- 可変長引数の本体での型は配列。
- 0個の呼出しは空配列でありnullではない。
- 可変長引数は最後に一つだけ宣言する。
- 配列宣言と...宣言だけの違いではオーバーロードできない。
間違えやすい点
- 可変長引数の要素数と固定引数の個数を混同しない。
- 配列を直接渡しても必ず複製されると思わない。
- null配列とnull要素を区別する。
用語解説
- 可変長引数
- 0個以上の引数をまとめて受け取れる末尾の配列型仮引数。
- 固定引数
- 個数と位置が決まった通常の仮引数。
- 空配列
- 要素数が0の配列オブジェクト。
- 配列直接指定
- 既存の配列参照を可変長引数の配列型へ渡す呼出し。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。