配列の添字とlengthを理解する
配列のlengthは要素数を表し、添字はその中の位置を指定します。0からlength-1までという境界を基準に、範囲外・null・型不一致を区別し、安全なループと末尾参照を組み立てます。
この単元で学ぶこと
- lengthから有効添字の範囲を求める
- 配列参照時の例外とコンパイルエラーを区別する
- 境界条件を守るループを追う
本文解説
要素数と位置を分ける int[] a={10,20,30};でa.lengthは3です。有効添字は0,1,2であり、a[3]は四番目を求めるため存在しません。長さを最後の添字と混同しないことが配列操作の基本です。
lengthはフィールド 配列ではa.lengthと書き、括弧を付けません。Stringのs.length()と形が違います。a.length()はメソッドがないため不正です。lengthはfinalなのでa.length=5という代入もできません。
末尾を参照する 長さ1以上ならa[a.length-1]が最後の要素です。長さ0では-1になり範囲外です。末尾処理の前にa.length>0を調べる方法があります。配列参照自体がnullの可能性があれば、その検査をさらに先に行います。
境界エラーは実行時 a[-1]やa[a.length]はArrayIndexOutOfBoundsExceptionです。添字式の型が適合していれば、リテラルの範囲外でも一般にコンパイルは通り、アクセス時に失敗します。宣言だけで範囲を保証できる仕組みではありません。
添字として使える型 int添字のほかbyte、short、charは数値昇格して使えます。longやdoubleはそのまま添字にできません。long i=0;でもa[i]は拒否されます。値の範囲と静的な型の制約を別に確認します。
全要素走査の条件 for(int i=0;i<a.length;i++)なら0から最後までです。i<=a.lengthだと最後にlengthそのものを使い範囲外になります。初期i=1では先頭を飛ばし、i<a.length-1では末尾を飛ばすので、単に例外が出ないだけでは全要素を処理したとはいえません。
nullとの違い int[] a=null;a.lengthはNullPointerExceptionです。int[] a=new int[0];a.lengthは0です。前者は実体がなく、後者は要素0個の実体があります。例外名から実体がないのか添字が範囲外なのかを切り分けます。
長さは実体ごとに固定 a=new int[5]と再代入するとa.lengthは5になりますが、古い実体の長さを変更したのではありません。別変数bが古い配列を指していればb.lengthは元の値です。長さを変える操作は実体の変更か参照の付替えかで整理します。
図解
重要ポイント
- lengthはメソッドでなくfinalのフィールド。
- 添字は0以上かつlength未満。
- 負の添字やlengthと等しい添字は実行時例外。
- long添字は値が小さくても直接使えない。
間違えやすい点
- length()とlengthを混同しない。
- i<=a.lengthを全要素走査に使わない。
- 空配列でa[a.length-1]を無条件に参照しない。
用語解説
- length
- 配列実体の要素数を返すint型のfinalフィールド。
- 範囲外添字
- 0未満またはlength以上の添字。
- 境界検査
- 要素アクセス時に添字が有効範囲かを確認する実行時検査。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
確認問題の出題・採点や学習履歴の保存にはログインが必要です。