java.lang.ArrayIndexOutOfBoundsExceptionエラーの解決方法を現役エンジニアが解説【初心者向け】
初心者向けにjava.lang.ArrayIndexOutOfBoundsExceptionエラーの解決方法について解説しています。これはJavaでよく発生するエラーのひとつです。ArrayIndexOutOfBoundsExceptionエラーの見かた、その原因と発生したときの解決方法について実際の例をもとに学習しましょう。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
java.lang.ArrayIndexOutOfBoundsExceptionエラーの解決方法を、TechAcademyのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。
Javaについてそもそもよく分からないという方は、Javaとは何なのか解説した記事を読むとさらに理解が深まります。
なお本記事は、TechAcademyのオンラインブートキャンプ、Java講座の内容をもとに作成しています。
今回は、Javaに関する内容だね!
どういう内容でしょうか?
java.lang.ArrayIndexOutOfBoundsExceptionエラーの解決方法について詳しく説明していくね!
お願いします!
java.lang.ArrayIndexOutOfBoundsExceptionエラーとは
Javaプログラムの実行時に ArrayIndexOutOfBoundsException というエラーが発生することがあります。
これは「実行時例外」と呼ばれているものの一つです。
例えば、配列のインデックスが範囲外になった場合などはこのエラーが表示されるでしょう。
エラーが起きても、Javaの文法としてコードに問題がないためコンパイルは正常に終了します。
しかし、プログラムを実行している最中に正常に処理できないケースが発生してしまったことを示しているため対処が必要です。
「実行時例外」が起きるとアプリがクラッシュしてしまうこともあるため、しっかり対応しておきましょう。
エラーの原因
下記は ArrayIndexOutOfBoundsException を引き起こすコードの一例です。
public class Sample { public static void main(String[] args) { String[] texts = new String[3]; setHello(texts, 3); } static void setHello(String[] texts, int index) { texts[index] = "こんにちは"; } }
上記のコードのどこに問題があるのか、それを探るためには、プログラムの実行時に「コンソール」に表示された情報をヒントにしましょう。
たとえば、上記のコードを実行すると下記のような情報が「コンソール」に表示されます。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at Sample.setHello(Sample.java:9) at Sample.main(Sample.java:5)
上記のようなエラー表示は一般に「例外のスタックトレース」と呼ばれています。
Eclipse や Android Studio などのたいていの開発環境では、上記のような表示が何行かにわたって赤い色の文字で「コンソール」に表示されます。
一番上の行では「何が」起きたか、二行目以降には「どこで」起きたかを表示している状態です。
そして、ArrayIndexOutOfBoundsException の表記を、日本語に訳すと「配列のインデックス(添え字)が範囲外になった例外」と表せます。
例を見てみると、一番上の行の右側には数値として3が表示されています。これは、配列を参照するためのインデックスに3という数値が指定されたことを意味しているものです。
では、長さが3の配列にアクセスする際、インデックスに3を指定することの何処に問題があるのでしょうか。
Javaで配列を扱うとき、各要素のデータにアクセスするためのインデックスは、0から始まります。
具体的に言うと、Javaの配列の
1番目の要素のインデックスは 0、
2番目の要素のインデックスは 1、
3番目の要素のインデックスは 2、
ということになります。
つまり、長さが3の配列の最後の要素にアクセスする際のインデックスは3ではありません。
この場合の有効なインデックスの最大値は2です。
インデックスの値に2より大きい値、つまり3以上の値を指定すると、ArrayIndexOutOfBoundsException 、「配列のインデックスが範囲外になってしまった例外」が起きます。
配列に指定するインデックスは配列のサイズ「未満」でなければならないことを覚えておきましょう。
注意点として、配列のインデックスは、マイナス値を指定してもエラーとなります。
ですので、必ず0以上にしましょう。
ここまでの解説で「何が」問題だったのかという点ははっきりしました。
では、「どこで」問題が起きたかを確認していきましょう。
以下、エラーが起きるスタックトレースです。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at Sample.setHello(Sample.java:9) at Sample.main(Sample.java:5)
上記のエラーメッセージの二行目以降は、それぞれ 場所を示すat という表記で始まっています。
この表示から「例外のスタックトレース」の二行目以降は、プログラム内のどの部分を実行している時に問題が発生したのかを示しています。
このエラーメッセージは時系列的として、一番下から順に読んでいきましょう。
上記の例では、まず Sample.java の5行目、次に9行目を通って、そこで ArrayIndexOutOfBoundsException が生じていることが読み取れます。
そして、上記の例外を発生させたコードSample.java の9行目は下記の内容です。
texts[index] = "こんにちは";
これで「どこで」「何が」起きているのかがわかりました。では、解決策をみていきましょう。
エラーの解決策
ArrayIndexOutOfBoundsException の一番オーソドックスな対応方法は、配列の要素にアクセスする直前に、インデックスの値が「0以上」かつ「配列のサイズ未満」であることを確認することです。
例えば、下記のようになります。
if(0<=index && index<texts.length) { texts[index] = "こんにちは"; }
上記のようにすれば、ArrayIndexOutOfBoundsExceptionは起きません。
しかし、これだけではプログラムの呼び出し側に間違って 変数(index)にマイナス値を指定してしまったり、配列のサイズ以上の値を指定してしまったりした場合に一切何も起きなくなってしまいます。
この場合、アプリがクラッシュするようなことはなくなったものの、同時にプログラムの実行時のエラーが一切表面化することもなくなりました。そのため、将来的なバグの温床となる可能性があるといえるでしょう。
そのため、if文の後に else を追記し、何らかのエラー処理を入れておくことで対処可能です。
下記のコードはその例となります。
if(0<=index && index<texts.length) { texts[index] = "こんにちは"; } else { System.out.println("指定されたインデックスの値が不正です。index = " + index); }
上記ではelseの処理の中で、コンソールにエラーメッセージが表示されるようにしました。
これでエラーが消されてしまうことはなくなったため、デバッグの際に問題に気付くでしょう。
配列のインデックスが有効な範囲外である場合の処理は、この対処以外にも色々と方法はあります。
しかし、ArrayIndexOutOfBoundsExceptionが生じてしまったときは、その場で例外が発生しないようにする対処をするだけでは適切な対処とはいえません。
なぜ配列のインデックスに範囲外の数値が指定されているのかプログラムの流れ全体を確認することも大切です。
監修してくれたメンター
野崎英一
プログラマ。SoftCommu代表。 |
java.lang.ArrayIndexOutOfBoundsExceptionエラーの解決方法がよくわかりました!
ゆかりちゃん、これからも分からないことがあったら質問してね!
分かりました。ありがとうございます!
TechAcademyでは、初心者でも、JavaやServletの技術を使ってWebアプリケーション開発を習得できる、オンラインブートキャンプを開催しています。
また、現役エンジニアから学べる無料体験も実施しているので、ぜひ参加してみてください。