メソッド宣言と可変長引数のコードトレース

可変長引数を集計やオーバーロードと組み合わせます。渡された値の個数と、既存配列を直接渡したときの共有を実行結果で確認します。

この単元で学ぶこと

  • 可変長引数を配列として説明する
  • 宣言位置と呼出しの合法性を判定する
  • 配列・null・オーバーロードの結果を追う

本文解説

集計して返す static int sum(int... xs){int s=0;for(int x:xs)s+=x;return s;}ではsum(1,2,3)は6、sum()は0です。初期値0と空配列なら本体0回という二つの理由を確認します。配列のlengthは合計値ではありません。

固定引数の役割 static int f(int factor,int... xs){int s=0;for(int x:xs)s+=x;return factor*s;}にf(2,3,4)と渡すと14です。factorはxsへ含まれず、xsは{3,4}です。引数をどこで区切るかを宣言と対応させます。

配列を並べ直さない int[] a={4,5};sum(a)なら二要素の合計9です。sum(4,5)も同じ計算結果ですが、前者は既存配列の参照を渡します。要素を変更するメソッドなら、呼出し後のaにも変更が見えます。

配列の再代入 static void f(int... xs){xs=new int[]{9};}へ既存aを渡してもaの参照は変わりません。これは通常の配列引数と同じ値渡しです。一方xs[0]++なら同じ配列の要素を変えます。...は値渡しの規則を変更しません。

参照型要素のnull static int f(String... xs){return xs[0].length();}へ(String)nullを渡すと、配列は一要素ありますがその要素がnullなので本体で例外です。空引数なら添字の範囲外、(String[])nullなら配列参照がnullであり、原因が異なります。

固定個数として適用 f(Object)とf(int...)にint[]を直接渡す場合、配列型int[]に一致する後者のほうが限定的です。可変長として要素をまとめる必要がないため、初期の適用段階で配列引数のメソッドとして候補に入ります。

基本型の変換 long...はintの値をlongへ拡大してまとめられますが、既存のint[]をlong[]へ自動変換して渡すことはできません。f(1,2)とf(new int[]{1,2})は、実引数の型も変換の対象も異なります。

検証表 引数リスト、固定引数、末尾配列の型と長さ、変更した要素、戻り値を並べます。intとlongの配列差、null配列とnull要素、固定個数として適用できる候補を別ケースにし、出力とコンパイル診断を確認します。

図解

可変長引数の受取方
どの呼出しでも本体のxsは配列型だが、空・null・共有の違いがある。

重要ポイント

  • 可変長引数の本体での型は配列。
  • 0個の呼出しは空配列でありnullではない。
  • 可変長引数は最後に一つだけ宣言する。
  • 配列宣言と...宣言だけの違いではオーバーロードできない。

間違えやすい点

  • 可変長引数の要素数と固定引数の個数を混同しない。
  • 配列を直接渡しても必ず複製されると思わない。
  • null配列とnull要素を区別する。

用語解説

可変長引数
0個以上の引数をまとめて受け取れる末尾の配列型仮引数。
固定引数
個数と位置が決まった通常の仮引数。
空配列
要素数が0の配列オブジェクト。
配列直接指定
既存の配列参照を可変長引数の配列型へ渡す呼出し。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。