
Java超|配列の範囲外アクセスと例外
予想外のトラブルも、例外の合図を読めば落ち着いて対処できる。Javaの例外は、危険な処理を知らせてくれる戦士本部の警報です。
Javaのプログラムは、書いた通りに正しく動いてくれるのが理想です。
しかし、実際にプログラムを動かしてみると、思いがけない問題が起きることがあります。
たとえば、用意していない場所にアクセスしようとしたり、数字として扱うつもりだった値が数字ではなかったり、存在するはずのファイルやデータが見つからなかったりする場合です。
Javaには、このような 実行中のトラブル を知らせるしくみがあります。
それが 例外 です。
例外は、プログラムが「このままでは処理を続けられません」と知らせてくれる合図です。
ただ止まるだけではなく、どんな種類の問題が、どのあたりで起きたのかを教えてくれます。
ドラゴンボール風にたとえると、悟空たちが任務中に、想定外の危険に出会ったようなものです。
| 任務中の出来事 | Javaでのイメージ |
|---|---|
| 5人分しかない戦士名簿の10番目に記録しようとする | 配列の範囲外にアクセスする |
| 戦闘力として読むはずの札に文字が書かれている | 数値変換に失敗する |
| カプセル保管庫にあるはずの道具記録が見つからない | ファイルやデータが見つからない |
| 危険な任務指令が出て警報が鳴る | 例外が発生する |
例外は、プログラムの失敗をただ知らせるだけのものではありません。
どこで何が起きたのかを知るための重要な手がかりでもあります。
この記事では、例外とは何か、コンパイルエラーと何が違うのか、配列の範囲外アクセスでは何が起きるのかを、ドラゴンボールの世界観に置きかえてやさしく整理していきます。
例外とは何か
例外とは、プログラムの実行中に起こる異常な出来事を表すしくみです。
Javaの文法としては正しく書けていても、実際に動かしたときの値や状況によって、処理を続けられないことがあります。
ドラゴンボール風に考えてみましょう。
悟空たちの戦士本部には、戦闘力を記録する名簿があります。
その名簿には、5人分の欄しかありません。
ところが、任務管理プログラムが、存在しない10番目の欄に戦闘力を記録しようとしました。
このとき、戦士本部の管理システムは「その欄は存在しません」と警告を出します。
存在しない場所へ無理に書き込むことはできないからです。
Javaでも同じです。
配列に5個分の場所しか用意していないのに、10番目へアクセスしようとすると、Javaは「その番号は範囲外です」と知らせます。
これが例外です。
| Javaで起きること | ドラゴンボール風のイメージ |
|---|---|
| 配列の範囲外にアクセスする | 戦士名簿の存在しない欄に記録しようとする |
| 数値変換に失敗する | 戦闘力札に数字ではない文字が書かれている |
| ファイルが見つからない | カプセル保管庫にあるはずの巻物がない |
| 例外が発生する | 戦士本部の警報システムが処理を止める |
ここで大切なのは、例外は 実行してはじめて分かるトラブル だという点です。
プログラムの文法が正しくても、実際の処理内容によって問題が起こることがあります。
コンパイルエラーと例外の違い
例外を理解するときは、コンパイルエラーとの違いを押さえると分かりやすくなります。
コンパイルエラーは、実行前に見つかる問題です。
たとえば、セミコロンを忘れた、変数名を間違えた、型が合わない、というような文法上の問題です。
一方、例外は、実行中に起こる問題です。
文法は正しくても、実際に動かしたときに不正な値や不正な操作が出てくると発生します。
| 種類 | いつ分かるか | 例 | ドラゴンボール風のイメージ |
|---|---|---|---|
| コンパイルエラー | 実行前 | 文法ミス、型の不一致、セミコロン忘れ | かめはめ波の構えが間違っていて技を出せない |
| 例外 | 実行中 | 配列の範囲外アクセス、数値変換失敗 | 技は出たが、任務中に想定外の危険が起きる |
ドラゴンボール風に言えば、コンパイルエラーは出発前の点検で見つかる不備です。
戦闘服の装着手順が間違っている、スカウターの設定式が壊れている、指令書の形式が崩れているような状態です。
例外は、任務に出てから起こるトラブルです。
道が崩れていた、カプセル保管庫が空だった、名簿の存在しない欄を参照してしまった、というような状況です。
どちらも問題ではありますが、見つかるタイミングが違います。
例外が起きる流れ
例外は突然出てくるように見えますが、実行中にはある程度はっきりした流れがあります。
| 順番 | 起きること |
|---|---|
| 1 | プログラムが上から順番に処理を進める |
| 2 | 実行中に不正な状況に出会う |
| 3 | Javaがその問題を例外として知らせる |
| 4 | 対応がなければ、その場で通常処理が止まる |
Javaでは、例外が発生することを 例外が送出される といいます。
これは、「このままでは処理を続けられません」という情報が、プログラムの中で投げられるようなイメージです。
ドラゴンボール風にたとえると、戦闘中にスカウターが危険な異常値を検知して、戦士本部へ警告を飛ばすようなものです。
「その場所には進めません」
「その記録欄は存在しません」
「その値は扱えません」
このような警告が、Javaでは例外として表れます。
図:例外が発生する基本の流れ

この図が示していること
この図は、例外が発生するまでの流れを表しています。
最初は、プログラムが上から順番に処理を進めます。
その途中で、存在しない場所にアクセスするような不正な状況に出会うと、Javaは例外を発生させます。
対応が用意されていない場合、その場所で通常の処理は止まります。
| 図の流れ | 意味 |
|---|---|
| 処理を進める | プログラムが通常通り動いている |
| 不正な状況 | 処理を続けられない問題に出会う |
| 例外が発生 | Javaが問題を知らせる |
| 対応がなければ停止 | 後続の処理が実行されない |
この図から分かることは、例外は何となく起きるものではなく、実行中の不正な操作をきっかけに発生するということです。
配列の範囲外アクセスで例外を見てみる
ここでは、例外の基本をつかむために、配列を使ったシンプルな例を見てみます。
今回のプログラムでは、5人分の戦士の戦闘力を記録するために、int 型の配列 power を用意します。
配列の要素数は5です。
つまり、使える番号は 0番目から4番目までです。
ところが、プログラムでは 10番目 に戦闘力を記録しようとします。
これは、用意されていない戦士名簿の欄に無理やり記録しようとしている状態です。
ファイル名:Sample1.java
class Sample1
{
public static void main(String[] args)
{
int[] power;
power = new int[5];
System.out.println("戦士リストの10番目に戦闘力を記録します。");
power[10] = 9000;
System.out.println("10番目に戦闘力9000を記録しました。");
System.out.println("修行記録の登録が完了しました。");
}
}配列 power が持っている場所
このプログラムでは、次のように配列を作成しています。
int[] power;
power = new int[5];new int[5] は、int 型の値を5個入れられる配列を作るという意味です。
ただし、Javaの配列の添字は 0 から始まります。
| 要素数 | 使える添字 |
|---|---|
| 5 | 0, 1, 2, 3, 4 |
つまり、power 配列で使えるのは次の範囲です。
| 添字 | 使えるか |
|---|---|
| power[0] | 使える |
| power[1] | 使える |
| power[2] | 使える |
| power[3] | 使える |
| power[4] | 使える |
| power[5] | 使えない |
| power[10] | 使えない |
今回の問題は、次の行です。
power[10] = 9000;power[10] は、5個分しかない配列の範囲を大きく超えています。
ドラゴンボール風にたとえると、5人分の戦士名簿しかないのに、10番目の欄へ戦闘力を書こうとしている状態です。
存在しない欄には記録できません。
そのため、Javaは例外を発生させます。
実行すると何が起きるのか
このプログラムを実行すると、最初のメッセージは表示されます。
戦士リストの10番目に戦闘力を記録します。
しかし、その次の行で配列の範囲外アクセスが起こります。
power[10] = 9000;そのため、実行結果は次のような形になります。
戦士リストの10番目に戦闘力を記録します。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
at Sample1.main(Sample1.java:10)ここで表示されている内容は、怖い文字列のように見えるかもしれません。
しかし、読み方が分かれば、とても役に立つ情報です。
| 表示内容 | 意味 |
|---|---|
| Exception in thread "main" | main メソッドの実行中に例外が起きた |
| java.lang.ArrayIndexOutOfBoundsException | 配列の範囲外にアクセスした |
| Index 10 out of bounds for length 5 | 長さ5の配列に対して添字10を使った |
| at Sample1.main(Sample1.java:10) | Sample1.java の10行目あたりで問題が起きた |
Javaは、ただ「止まりました」とだけ言っているわけではありません。
どんな種類の問題なのか。
どの番号が不正だったのか。
配列の長さはいくつだったのか。
どのファイルのどの行で起きたのか。
このような情報を教えてくれています。
後ろのメッセージが表示されない理由
Sample1.java には、次のメッセージも書かれています。
System.out.println("10番目に戦闘力9000を記録しました。");
System.out.println("修行記録の登録が完了しました。");しかし、実行結果には表示されません。
理由は、その前の行で例外が起きているからです。
power[10] = 9000;対応が用意されていない状態で例外が発生すると、通常の処理はそこで止まります。
そのため、その後ろに書かれている文は実行されません。
ドラゴンボール風にたとえると、戦士名簿に記録している途中で、存在しない欄を指定してしまったようなものです。
管理システムが「その欄はありません」と止めるため、
「記録しました」
「登録が完了しました」
という次の報告には進めません。
| 処理 | 実行されるか |
|---|---|
| 最初のメッセージ表示 | 実行される |
| power[10] = 9000; | ここで例外が起きる |
| 10番目に戦闘力9000を記録しました。 | 実行されない |
| 修行記録の登録が完了しました。 | 実行されない |
例外が発生した位置より後ろの通常処理は、何も対策していない場合は進まない。
ここはとても大切なポイントです。
図:配列の範囲外アクセスで例外が起きる

この図が示していること
この図は、配列 power の使える範囲と、実際にアクセスしようとした場所のズレを表しています。
power = new int[5] によって、配列には5個分の場所が用意されます。
ただし、添字は 0 から始まるため、使えるのは power[0] から power[4] までです。
power[10] は、その範囲の外にあります。
| 要素 | 意味 |
|---|---|
| power[0] 〜 power[4] | 実際に存在する配列の場所 |
| power[10] | 存在しない場所 |
| ArrayIndexOutOfBoundsException | 配列の範囲外アクセスを知らせる例外 |
この図から分かることは、例外が偶然起きるのではなく、存在しない場所にアクセスしようとしたことが原因で発生するということです。
ArrayIndexOutOfBoundsException の意味
今回発生した例外は、ArrayIndexOutOfBoundsException です。
長い名前ですが、分けて見ると意味が分かりやすくなります。
| 部分 | 意味 |
|---|---|
| Array | 配列 |
| Index | 添字、番号 |
| OutOfBounds | 範囲外 |
| Exception | 例外 |
つまり、ArrayIndexOutOfBoundsException は、配列の添字が範囲外です という意味です。
今回の配列は、5個分の要素を持っています。
power = new int[5];そのため、使える添字は 0, 1, 2, 3, 4 です。
しかし、実際には 10 を指定しました。
power[10] = 9000;そのため、Javaは ArrayIndexOutOfBoundsException を発生させました。
| 配列の長さ | 使える添字 | 指定した添字 | 結果 |
|---|---|---|---|
| 5 | 0〜4 | 10 | 範囲外なので例外 |
初心者がつまずきやすいのは、配列の要素数と添字を混同するところです。
5個分の配列だから 5番目まで使える、と思ってしまうことがあります。
しかし、Javaの配列は 0 から数えるため、5個分なら最後は 4番目です。
| 感覚的な数え方 | Javaの添字 |
|---|---|
| 1個目 | 0 |
| 2個目 | 1 |
| 3個目 | 2 |
| 4個目 | 3 |
| 5個目 | 4 |
ドラゴンボール風にたとえると、戦士名簿には5つの欄があります。
ただし、Javaの名簿では欄番号が 0 から始まるため、最後の欄は 4番です。
例外メッセージは原因を探す手がかり
例外メッセージは、最初は難しく見えます。
しかし、見るべきポイントを決めておくと、かなり読みやすくなります。
今回の実行結果をもう一度見てみます。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5
at Sample1.main(Sample1.java:10)この中で、特に見るべきポイントは次の3つです。
| 確認する場所 | 分かること |
|---|---|
| 例外名 | どんな種類の問題か |
| 詳細メッセージ | どの値が不正だったか |
| at から始まる行 | どのファイルのどの行で起きたか |
今回なら、次のように読み取れます。
| 情報 | 読み取れること |
|---|---|
| ArrayIndexOutOfBoundsException | 配列の範囲外アクセス |
| Index 10 out of bounds for length 5 | 長さ5の配列に対して10を指定した |
| Sample1.java:10 | Sample1.java の10行目あたりで起きた |
つまり、例外メッセージは、ただのエラー表示ではありません。
原因を探すための地図のようなものです。
ドラゴンボール風に言えば、戦士本部の警報システムが「どの任務で、どの地点で、どんな異常が起きたか」を知らせてくれている状態です。
例外が送出されるとはどういうことか
Javaでは、例外が起きることを 例外が送出される と表現します。
送出という言葉は少し硬いですが、イメージとしては「異常事態の情報が投げられる」ということです。
プログラムが処理を進めている途中で、続行できない問題に出会ったとき、Javaは例外オブジェクトという形で問題を知らせます。
ここでは、詳しい例外処理の文法までは扱いません。
まずは、例外が「実行中の異常を知らせる信号」として発生することを押さえれば大丈夫です。
ドラゴンボール風にたとえると、危険な惑星での任務中に、スカウターが異常な戦闘力反応を検知して警報札を飛ばすようなものです。
その警報札には、次のような情報が含まれます。
| 警報札の情報 | Javaの例外情報 |
|---|---|
| どんな危険か | 例外名 |
| どこで起きたか | ファイル名と行番号 |
| 何が原因か | 詳細メッセージ |
| その後どうなるか | 対応がなければ処理停止 |
例外は単なる失敗ではなく、問題を伝えるための仕組み化された信号です。
例外は怖いものではなく学習の手がかり
はじめて例外を見ると、英語の長い名前や複数行のメッセージに驚くかもしれません。
しかし、例外は学習の敵ではありません。
むしろ、何がまずかったのかを教えてくれる案内役です。
今回なら、Javaは次のことを教えてくれています。
| Javaが教えてくれていること | 内容 |
|---|---|
| 問題の種類 | 配列の範囲外アクセス |
| 不正な値 | 添字 10 |
| 配列の長さ | 5 |
| 問題の場所 | Sample1.java の10行目あたり |
これだけ分かれば、確認する場所はかなり絞れます。
初心者のうちは、例外が出たら次の順番で見ると分かりやすいです。
| 確認すること | 見るポイント |
|---|---|
| 例外名 | 何が原因かの大まかな種類 |
| 詳細メッセージ | どの値や条件が問題か |
| 行番号 | どの行で起きたか |
| 直前のコード | 何をしようとしていたか |
| 値や範囲 | 配列の長さ、入力値、添字など |
例外が出たら、まず落ち着いて例外名と行番号を見る。
この習慣がつくと、エラー対応がぐっと楽になります。
図:例外メッセージの読み方

この図が示していること
この図は、例外メッセージのどこを読めばよいのかを表しています。
例外メッセージには、主に次の情報が含まれます。
| 見る場所 | 分かること |
|---|---|
| Exception in thread "main" | main の実行中に起きた |
| ArrayIndexOutOfBoundsException | 配列の範囲外アクセス |
| Index 10 out of bounds for length 5 | 長さ5の配列に10を指定した |
| Sample1.java:10 | 問題が起きた場所 |
この図から分かることは、例外メッセージはただの警告文ではなく、原因をたどるための地図だということです。
ドラゴンボール風に例外を整理する
例外の考え方を、ドラゴンボール風にもう一度整理してみましょう。
| ドラゴンボール風の場面 | Javaでの考え方 |
|---|---|
| 5人分の戦士名簿しかないのに10番目へ記録する | 配列の範囲外アクセス |
| 戦闘力の札として読むはずが文字札だった | 数値変換の失敗 |
| 任務用のカプセル記録が保管庫にない | ファイルやデータが見つからない |
| 危険を知らせるスカウター警報が飛ぶ | 例外が送出される |
| 警報に対応しなければ任務が止まる | 例外処理がないとプログラムが停止する |
このように考えると、例外はJavaが勝手に怒っているわけではありません。
むしろ、危険な処理や不正な状況を見つけて、きちんと知らせてくれている状態です。
例外が出たら、まず次のように考えるとよいです。
| 考え方 | 内容 |
|---|---|
| 何が起きたのか | 例外名を見る |
| どこで起きたのか | ファイル名と行番号を見る |
| なぜ起きたのか | 詳細メッセージと直前のコードを見る |
| どの値が問題か | 添字、入力値、配列の長さなどを見る |
今回の Sample1.java では、power[10] が問題でした。
配列の長さは5なので、使えるのは power[0] から power[4] までです。
この範囲を超えたため、ArrayIndexOutOfBoundsException が発生しました。
これからの例外処理につながる考え方
ここで学んだのは、例外の基本です。
まず押さえておきたいことは、次の4つです。
| 基本 | 内容 |
|---|---|
| 例外は実行中に起きる | 文法が正しくても、動かして初めて分かる問題がある |
| 例外には種類がある | ArrayIndexOutOfBoundsException など |
| 例外が起きると処理が止まることがある | 対応がない場合、後続の通常処理は進まない |
| 例外メッセージには手がかりがある | 原因、場所、問題の値を確認できる |
この考え方が分かると、この先で学ぶ try や catch の意味も理解しやすくなります。
try や catch は、例外が起きそうな処理に備えて、プログラムがその場で完全に止まらないようにするためのしくみです。
ドラゴンボール風にたとえると、危険な任務に出る前に、ピッコロの支援、ブルマの通信装置、仙豆、退避ルートを用意しておくようなものです。
何も準備していなければ、想定外の事態で任務が止まります。
しかし、事前に対応方法を決めておけば、状況を確認して別の処理へ進める可能性があります。
今回の段階では、まず次の感覚をつかむことが大切です。
例外は、実行中の異常を知らせる合図であり、原因を探すための手がかりでもある。
この感覚があると、例外メッセージを見たときに、ただ驚くのではなく、落ち着いて読み解けるようになります。
