ArrayIndexOutOfBoundsException の原因と直し方
添字が0始まりであることの帰結です。ループ条件の < と <= の使い分けを整理します。
エラーメッセージの読み方
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
main- スレッド名 — mainなら起動直後の処理で発生しています
java.lang- パッケージ — java.lang なら標準の基本例外です
ArrayIndexOutOfBoundsException- 例外クラス — 何が起きたか。ここを検索するのが最短です
このエラーが出る典型パターン
パターン1
1 public class Main { 2 public static void main(String[] args) { 3 int[] nums = {10, 20, 30}; 4 for (int i = 0; i <= nums.length; i++) { ^ 5 System.out.println(nums[i]); 6 } 7 } 8 }
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 3 out of bounds for length 3exited with code 1
長さ3の配列の添字は0,1,2です。全要素を回るループは < が正解です。
直し方: <= を < にします。
広告
広告スロット(未設定)
パターン2
1 public class Main { 2 public static void main(String[] args) { 3 int[] nums = {10, 20, 30}; 4 System.out.println(nums[nums.length ]); ^ 5 } 6 }
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 3 out of bounds for length 3exited with code 1
最後の要素の添字は length - 1 です。添字が0始まりであることの直接的な帰結です。
直し方: nums.length を nums.length - 1 にします。
パターン3
1 public class Main { 2 public static void main(String[] args) { 3 int[] nums = new int[3]; 4 for (int i = -1 ; i < nums.length; i++) { ^ 5 nums[i] = i; 6 } 7 System.out.println(nums[0]); 8 } 9 }
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index -1 out of bounds for length 3exited with code 1
負の添字も範囲外です。Javaでは末尾から数える書き方はできません。
直し方: -1 を 0 にします。
パターン4
1 public class Main { 2 public static void main(String[] args) { 3 int[] nums = {10, 20, 30}; 4 for (int i = nums.length ; i >= 0; i--) { ^ 5 System.out.println(nums[i]); 6 } 7 } 8 }
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 3 out of bounds for length 3exited with code 1
逆順ループの開始位置も length - 1 です。最後の要素の添字は length ではありません。
直し方: nums.length を nums.length - 1 にします。
パターン5
1 public class Main { 2 public static void main(String[] args) { 3 int[] nums = new int[0 ]; ^ 4 System.out.println(nums[0]); 5 } 6 }
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 0 out of bounds for length 0exited with code 1
サイズ0の配列には要素が1つもありません。使う前に配列の大きさを確認する習慣が大切です。
直し方: 0 を 1 にします。
よくある誤解
例外メッセージの Index N が、実際に触った添字です。ループ条件を睨む前にこの数字を読むと原因が早く分かります。
実務での勘所
配列の範囲外アクセスは、C言語のように未定義動作としてメモリを壊すのではなく、JVMが毎回の添字アクセスで境界を検査し、範囲外なら必ず例外を投げるという設計です。この検査には多少の実行コストがありますが、安全性を優先した設計判断です。添字そのものを使わずに要素を順に処理するだけなら、for (int i = 0; i < arr.length; i++)の代わりにfor (int x : arr)という拡張for文を使えば、そもそも添字を書かないためこの種のミスが原理的に起きません。
関連するエラー
- ループが終わらない・空回りする原因カウンタ更新の忘れ、更新方向の誤り、forの直後のセミコロンという3パターンを扱います。
- ConcurrentModificationException の原因と直し方ループ中のリスト変更で発生します。
- 配列の new と初期化子の書き分けnew int[3] と {1,2,3} の使い分け。