java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0 は、要素が0個(空)のリストから、0番目を取り出そうとしたときの例外です。 length 0 が「リストの要素数」、Index 0 が「取り出そうとした番号」です。

List<String> list = new ArrayList<>();   // 空
System.out.println(list.get(0));          // ← 例外
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
    at java.base/java.util.Objects.checkIndex(Objects.java:385)
    at java.base/java.util.ArrayList.get(ArrayList.java:427)
    at S.main(S.java:2)

番号は 0 から length - 1 までです。 例外が出るのは「番号 ≧ length」か「番号がマイナス」のときです。

メッセージ 意味 よくある原因
Index 0 out of bounds for length 0 空のリストの0番目 検索結果が0件なのに get(0)
Index 3 out of bounds for length 3 3個のリストの3番目(最後は2) i <= list.size() のループ
Index -1 out of bounds for length 3 マイナスの番号 indexOf が見つからず -1 を返した
Index 3 out of bounds for length 2 途中で要素が減った ループ中に remove(i)

確認環境:OpenJDK 21.0.10(Linux)で再現しました(確認日 2026年10月12日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Index 0 out of bounds for length 0の直し方」

まず、スタックトレースで「自分のコードの行」を探す

上の例では、at S.main(S.java:2) が自分のコードの行です。java.base/ で始まる行は Java の中の処理なので飛ばし、最初に出てくる自分のクラスの行を開きます。その行の get(...) などの番号と、そのときのリストの要素数を比べます。

System.out.println("size=" + list.size() + ", index=" + i);   // 例外の直前に足して確かめる

原因① 空のリストに get(0):検索結果が0件

一番多いのは、DBや検索の結果を「必ず1件はある」と思って get(0) する形です。 0件のときだけ例外になるので、テストで見落としやすい不具合です。

List<User> users = repository.findByEmail(email);
User user = users.get(0);   // ← 0件のとき Index 0 out of bounds for length 0

0件のときにどうするかを決めて、書き分けます。

0件のときにしたいこと 書き方
処理を分ける if (users.isEmpty()) { ... } else { users.get(0) }
無いことを値で返す users.stream().findFirst()(Optional<User>)
業務エラーにする users.stream().findFirst().orElseThrow(() -> new UserNotFoundException(email))
既定値を使う users.isEmpty() ? User.GUEST : users.get(0)
User user = users.stream()
        .findFirst()
        .orElseThrow(() -> new IllegalArgumentException("ユーザーが見つかりません: " + email));

例外のメッセージに「何を探して見つからなかったか」が入るので、Index 0 out of bounds よりログで原因が分かりやすくなります。

原因② ループの条件が i <= size()

要素が3個なら番号は 0・1・2 です。 <= にすると、最後に get(3) を呼んで例外になりました。

for (int i = 0; i <= list.size(); i++) {   // ← <= が原因
    System.out.println(list.get(i));       // Index 3 out of bounds for length 3
}
for (int i = 0; i < list.size(); i++) { ... }   // < にする
for (String s : list) { ... }                     // 番号が要らなければ拡張for文

番号を使わないループは、拡張for文にすると範囲外の心配がありません。

原因③ ループ中に remove(i) して、要素が減った

最初に数えた件数でループしたまま remove すると、途中で要素が足りなくなります。 [1, 2, 3, 4] から偶数を消そうとして、Index 3 out of bounds for length 2 になりました。

List<Integer> nums = new ArrayList<>(List.of(1, 2, 3, 4));
int n = nums.size();                 // 4 で固定
for (int i = 0; i < n; i++) {
    if (nums.get(i) % 2 == 0) nums.remove(i);   // ← 要素が減るのに 4 回まわる
}
nums.removeIf(x -> x % 2 == 0);      // [1, 3]

条件に合う要素を消すなら removeIf が一番安全です。番号で消す必要があるときは、後ろから回します(for (int i = nums.size() - 1; i >= 0; i--))。

原因④ indexOf の -1 をそのまま使った

indexOf は見つからないと -1 を返します。そのまま get や substring に渡すと、Index -1 out of bounds になります。

int i = list.indexOf("X");
if (i >= 0) {
    list.get(i);
}

作り方によって、例外の名前とメッセージが変わる

同じ「範囲外」でも、リストの作り方や型によって、例外とメッセージが変わりました。どれも原因は同じ(番号が範囲外)です。

書き方 例外 メッセージ
new ArrayList<>().get(0) IndexOutOfBoundsException Index 0 out of bounds for length 0
List.of("A","B","C").get(3) ArrayIndexOutOfBoundsException Index 3 out of bounds for length 3
Arrays.asList(...).get(3) ArrayIndexOutOfBoundsException Index 3 out of bounds for length 3
new LinkedList<>(...).get(3) IndexOutOfBoundsException Index: 3, Size: 3
list.add(5, "X")(3個のリスト) IndexOutOfBoundsException Index: 5, Size: 3
list.subList(1, 5) IndexOutOfBoundsException toIndex = 5
int[] x = new int[3]; x[3] ArrayIndexOutOfBoundsException Index 3 out of bounds for length 3
"abc".charAt(3) StringIndexOutOfBoundsException Index 3 out of bounds for length 3
"abc".substring(0, 5) StringIndexOutOfBoundsException Range [0, 5) out of bounds for length 3

ArrayIndexOutOfBoundsException と StringIndexOutOfBoundsException は、IndexOutOfBoundsException の子クラスです。 catch するなら親の IndexOutOfBoundsException でまとめて受けられますが、まずは範囲外にならない書き方に直すのが先です。配列と文字列は、関連記事「Java ArrayIndexOutOfBoundsException原因と対処」「Java substringの使い方 末尾切り出しと範囲外エラーの直し方」で扱っています。

Java 21 の getFirst() は、空のとき別の例外になる

Java 21 で追加された getFirst()・getLast() は、空のリストでは NoSuchElementException でした。get(0) の代わりに使っても、空のときの扱いを決めないといけない点は同じです。

new ArrayList<String>().getFirst();   // java.util.NoSuchElementException

よくある質問

Q. Index 1 out of bounds for length 1 と出ました。 A. 要素が1個(番号は0だけ)のリストで、1番目を取り出そうとしています。split の結果を [1] で取るとき、区切り文字が無い行で起きやすい形です。length を確かめてから取り出します。

Q. テストでは出ず、本番だけで出ます。 A. データが0件・1件のときだけ起きる例外なので、テストデータに「0件」「1件」「最大件数」を入れて確かめます。境界の値の選び方は、関連記事「同値分割・境界値分析|テストケース表とpytestコード例で解説」で扱っています。

Q. try-catch で囲めばいいですか。 A. 範囲外は「番号の計算か、件数の前提が間違っている」合図です。catch で隠すと別の場所で不具合になるので、isEmpty() や findFirst() で0件の扱いを決めます。

Q. ConcurrentModificationException も出ました。 A. 拡張for文の途中でリストを変更したときの例外です。関連記事「ConcurrentModificationExceptionの原因と対処法」で扱っています。

まとめ

  • Index 0 out of bounds for length 0 は、空のリストの0番目を取った
  • 番号は 0 から length - 1。length が要素数
  • 多い原因は 0件の検索結果に get(0)、i <= size()、ループ中の remove、indexOf の -1
  • 0件は isEmpty()・findFirst()・orElseThrow() で扱いを決める
  • 消すなら removeIf、番号が要らないループは 拡張for文

参考・出典

確認日はいずれも 2026年10月12日です。

  • Java SE 21 API「IndexOutOfBoundsException」:https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/IndexOutOfBoundsException.html
  • Java SE 21 API「List」(get・getFirst):https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/List.html
  • Java SE 21 API「Collection.removeIf」:https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collection.html

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Index 0 out of bounds for length 0の直し方」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?