1. 概要

このチュートリアルでは、JavaのArrayIndexOutOfBoundsExceptionについて説明します。 それが発生する理由とそれを回避する方法を理解します。

2. ArrayIndexOutOfBoundsException はいつ発生しますか?

ご存知のように、Javaでは、 array は静的データ構造であり、作成時にそのサイズを定義します。

インデックスを使用して配列の要素にアクセスします。 配列のインデックスはゼロから始まり、配列のサイズ以上であってはなりません。

要するに、 経験則は0<=インデックス<(配列のサイズ)です。

ArrayIndexOutOfBoundsExceptionは、無効なインデックスを持つ配列に裏打ちされた配列またはコレクションにアクセスしたときに発生します。これは、インデックスがゼロ未満または配列のサイズ以上であることを意味します。

さらに、境界チェックは実行時に行われます。 したがって、ArrayIndexOutOfBoundsExceptionは実行時の例外です。 したがって、配列の境界要素にアクセスするときは特に注意する必要があります。

ArrayIndexOutOfBoundsExceptionにつながる一般的な操作のいくつかを理解しましょう。

2.1. 配列へのアクセス

配列へのアクセス中に発生する可能性のある最も一般的な間違いは、上限と下限を忘れることです。

配列の下限は常に0ですが、上限はその長さより1つ短くなります。

これらの境界外の配列要素にアクセスすると、ArrayIndexOutOfBoundsExceptionがスローされます。

int[] numbers = new int[] {1, 2, 3, 4, 5};
int lastNumber = numbers[5];

ここで、配列のサイズは5です。これは、インデックスの範囲が0から4であることを意味します。

この場合、5番目のインデックスにアクセスすると、ArrayIndexOutOfBoundsExceptionが発生します。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at ...

同様に、数値へのインデックスとしてゼロ未満の値を渡すと、ArrayIndexOutOfBoundsExceptionが発生します。

2.2. Arrays.asList()によって返されるリストへのアクセス

静的メソッドArrays.asList()は、指定された配列に基づく固定サイズのリストを返します。 さらに、アレイベースのAPIとコレクションベースのAPIの間のブリッジとして機能します。

この返されるListには、インデックスに基づいてその要素にアクセスするためのメソッドがあります。 また、配列と同様に、インデックス付けはゼロから始まり、そのサイズより1小さい範囲になります。

Arrays.asList()によって返される List の要素にこの範囲を超えてアクセスしようとすると、ArrayIndexOutOfBoundsExceptionが発生します。

List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5);
int lastNumber = numbersList.get(5);

ここでも、リストの最後の要素を取得しようとしています。 最後の要素の位置は5ですが、そのインデックスは4(サイズ– 1)です。 したがって、次のようにArrayIndexOutOfBoundsExceptionを取得します。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at java.base/java.util.Arrays$ArrayList.get(Arrays.java:4351)
    at  ...

同様に、負のインデックス、たとえば-1を渡すと、同様の結果が得られます。

2.3. ループでの反復

forループで配列を反復処理しているときに、間違った終了式を配置することがあります。

配列の長さより1つ短いインデックスで終了する代わりに、その長さまで反復することになります。

int sum = 0;
for (int i = 0; i <= numbers.length; i++) {
    sum += numbers[i];
}

上記の終了式では、ループ変数既存のアレイの長さ以下として比較されています数字。 したがって、最後の反復では、 5になります。

インデックス5は番号の範囲を超えているため、は再びArrayIndexOutOfBoundsExceptionになります。

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at com.baeldung.concatenate.IndexOutOfBoundExceptionExamples.main(IndexOutOfBoundExceptionExamples.java:22)

3. ArrayIndexOutOfBoundsException を回避する方法は?

ArrayIndexOutOfBoundsExceptionを回避するいくつかの方法を理解しましょう。

3.1. スタートインデックスを覚えている

Javaでは配列インデックスは0から始まることを常に覚えておく必要があります。したがって、最初の要素は常にインデックス0にあり、最後の要素は配列の長さより1短いインデックスにあります。

このルールを覚えておくと、ほとんどの場合ArrayIndexOutOfBoundsExceptionを回避するのに役立ちます。

3.2. ループ内の演算子を正しく使用する

ループ変数をインデックス1に誤って初期化すると、ArrayIndexOutOfBoundsExceptionが発生する可能性があります。

同様に、ループの終了式での演算子<、<=、>、または> =の誤った使用は、この例外が発生する一般的な理由です。

ループでのこれらの演算子の使用を正しく決定する必要があります。

3.3. ループに拡張を使用

アプリケーションがJava1.5以降のバージョンで実行されている場合は、コレクションと配列を反復処理するために特別に開発された拡張forループステートメントを使用する必要があります。 また、ループがより簡潔で読みやすくなります。

さらに、拡張forループを使用すると、インデックス変数が含まれないため、ArrayIndexOutOfBoundsExceptionを完全に回避できます

for (int number : numbers) {
    sum += number;
}

ここでは、インデックス作成について心配する必要はありません。 拡張されたforループは要素を取得し、反復ごとにループ変数numberに割り当てます。 したがって、ArrayIndexOutOfBoundsExceptionを完全に回避します。

4. IndexOutOfBoundsException対。 ArrayIndexOutOfBoundsException

IndexOutOfBoundsException は、あるタイプ( String 、配列、 List など)のインデックスにその範囲を超えてアクセスしようとすると発生します。 これは、ArrayIndexOutOfBoundsExceptionおよびStringIndexOutOfBoundsExceptionのスーパークラスです。

ArrayIndexOutOfBoundsException と同様に、 String の文字にその長さを超えるインデックスでアクセスしようとすると、StringIndexOutOfBoundsExceptionがスローされます。

5. 結論

この記事では、 ArrayIndexOutOfBoundsException 、それがどのように発生するかの例、およびそれを回避するためのいくつかの一般的な手法について説明しました。

いつものように、これらすべての例のソースコードはGitHubで入手できます。