
Java超|try-catchによる例外処理
予想外のトラブルも、try-catch があれば落ち着いて受け止められる。Javaの例外処理は、危険な任務に備える戦士本部の安全装置です。
プログラムを作っていると、いつも思いどおりに処理が進むとは限りません。
文法としては正しく書けていても、実行してみると、想定外の値が使われたり、存在しない場所へアクセスしてしまったりして、そのままでは処理を続けられないことがあります。
たとえば、5人分しか用意していない配列に対して、10番目の場所へ値を入れようとするような場合です。
このような実行中のトラブルに対応するために、Javaには 例外処理 というしくみがあります。
その基本になるのが try-catch です。
try-catch は、簡単に言えば、危険が起きるかもしれない処理と、問題が起きたときの対応を分けて書くためのしくみです。
| ブロック | 役割 |
|---|---|
| try | 例外が起きるかもしれない処理を書く場所 |
| catch | 例外が起きたときに受け止めて対応する場所 |
ドラゴンボール風にたとえると、危険な惑星へ悟空たちが任務に出る前に、ピッコロの支援、ブルマの通信装置、仙豆、退避ルートを用意しておくようなものです。
何も備えがないまま任務中に問題が起きると、その場で任務は中断してしまいます。
しかし、あらかじめ「この種類のトラブルが起きたら、ここで受け止める」と決めておけば、問題が起きても状況を確認し、次の処理へ進める可能性があります。
Javaの try-catch も同じです。
危険が起きるかもしれない処理を try に入れます。
実際に例外が起きたら、対応する catch がそれを受け止めます。
そして、catch で必要な処理をしたあと、try-catch の後ろの処理へ進めます。
この考え方を身につけると、エラーで突然止まるだけのプログラムから、トラブルに対応できるプログラムへ一歩進めるようになります。
例外処理とは何か
例外処理とは、実行中に問題が起きたときに、あらかじめ決めておいた方法で対応することです。
前に学んだように、配列の範囲をこえるような処理をすると、例外が発生します。
たとえば、次のような状態です。
| 状況 | Javaで起きること |
|---|---|
| 配列は5個分しかない | 使える添字は 0 から 4 |
| 10番目に値を入れようとする | 範囲外アクセスになる |
| 対応がない | プログラムが途中で終了する |
| try-catch がある | catch で受け止めて対応できる |
ドラゴンボール風に考えると、悟空たちの戦士本部にある修行名簿に、5人分の欄しかないのに、10番目の欄へ戦闘力を書き込もうとしている状態です。
何も備えがなければ、名簿管理の処理はそこで止まります。
しかし、支援担当のピッコロやブルマの警報システムが待機していて、
「その番号は使えません。登録できる範囲を確認してください」
と受け止めてくれれば、任務全体をいきなり終了させずに、状況を知らせることができます。
これが例外処理の考え方です。
例外処理は、問題をなかったことにする仕組みではありません。
問題が起きたときに、どう受け止め、どう知らせ、どこまで処理を続けるかを決める仕組みです。
try と catch の役割
try-catch は、try ブロックと catch ブロックで構成されます。
基本の形は次のようになります。
try {
例外が起きるかもしれない処理
}
catch(例外の種類 変数名) {
例外が起きたときの処理
}それぞれの役割を整理すると、次のようになります。
| ブロック | 役割 | ドラゴンボール風のイメージ |
|---|---|---|
| try | まず実行してみる処理を書く | 危険の可能性がある任務を進める場所 |
| catch | 例外が起きたときの対応を書く | 支援役が警告を受け止める場所 |
try は「ここで問題が起きるかもしれないけれど、まず処理を実行してみる」という場所です。
catch は「もし指定した種類の例外が起きたら、ここで受け止めて対応する」という場所です。
ドラゴンボール風に言えば、try は悟空たちが実際に任務を進める場面です。
catch は、異常が起きたときにピッコロやブルマの支援システムが警告を受け止める場面です。
try-catch の基本の流れ
try-catch の処理は、次のような流れで進みます。
| 順番 | 処理の流れ |
|---|---|
| 1 | try ブロックの中の処理を上から順に実行する |
| 2 | try の途中で例外が起きる |
| 3 | 例外が起きた地点で try の後続処理は中断される |
| 4 | 例外の種類に合う catch ブロックを探す |
| 5 | 一致する catch があれば、その中の処理を実行する |
| 6 | catch の処理後、try-catch の後ろへ進む |
ここで大切なのは、try の中で例外が起きた場合、try の残りの文がそのまま続けて実行されるわけではないということです。
例外が起きた場所で、try の通常の流れはいったん止まります。
そして、対応する catch へ処理が移ります。
図:try-catch の基本の流れ

この図が示していること
この図は、try の中で起きた例外が catch に渡される流れを表しています。
try では、危険が起きるかもしれない処理を実行します。
その途中で例外が発生すると、try の後続処理はいったん中断されます。
その後、例外の種類に合う catch が見つかると、その catch の中の処理が実行されます。
| 図の要素 | 意味 |
|---|---|
| try | 例外が起きるかもしれない処理 |
| 例外発生 | 処理を続けられない問題 |
| catch | 例外を受け止める場所 |
| 後続処理 | catch のあとに進む処理 |
この図から分かることは、try-catch は例外を消す仕組みではなく、例外が起きたときの流れを決める仕組みだということです。
try-catch 処理を確認する
ここでは、配列の範囲をこえる例外を try-catch で処理する例を見ていきます。
5人分の戦闘力を記録できる配列を用意します。
しかし、あえて 10番目 に戦闘力を登録しようとします。
通常なら、配列の範囲外アクセスでプログラムが途中で止まります。
今回は、その危険な処理を try に入れ、ArrayIndexOutOfBoundsException が起きたときの対応を catch に書きます。
ファイル名:Sample2.java
class Sample2
{
public static void main(String[] args)
{
try {
int[] power;
power = new int[5];
System.out.println("戦士本部の修行名簿の10番目に戦闘力を登録します。");
power[10] = 9000;
System.out.println("10番目に戦闘力9000を登録しました。");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("登録できる範囲をこえています。");
}
System.out.println("修行記録の確認を終えました。");
}
}このプログラムの全体像
このプログラムでは、try ブロックの中に、例外が起きる可能性のある処理を書いています。
try {
int[] power;
power = new int[5];
System.out.println("戦士本部の修行名簿の10番目に戦闘力を登録します。");
power[10] = 9000;
System.out.println("10番目に戦闘力9000を登録しました。");
}配列 power は、次のように作成されています。
int[] power;
power = new int[5];new int[5] によって、5個分の int 型データを入れる場所が作られます。
ただし、Javaの配列の添字は 0 から始まります。
| 配列の要素数 | 使える添字 |
|---|---|
| 5 | 0, 1, 2, 3, 4 |
そのため、使えるのは power[0] から power[4] までです。
しかし、try の中では次のように書いています。
power[10] = 9000;これは、存在しない10番目の場所に値を入れようとしている状態です。
ドラゴンボール風にたとえると、5人分しかない修行名簿に、10番目の戦士の戦闘力を書き込もうとしているようなものです。
そのため、この行で ArrayIndexOutOfBoundsException が発生します。
catch が例外を受け止める
例外が発生すると、対応する catch ブロックへ処理が移ります。
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("登録できる範囲をこえています。");
}この catch の丸かっこの中には、次の2つが書かれています。
| 部分 | 意味 |
|---|---|
| ArrayIndexOutOfBoundsException | 受け取りたい例外の種類 |
| e | 受け取った例外を入れる変数名 |
今回発生する例外は ArrayIndexOutOfBoundsException です。
catch も ArrayIndexOutOfBoundsException を受け取る形になっています。
そのため、例外の種類が一致し、catch の中の処理が実行されます。
ドラゴンボール風に言えば、
「名簿の範囲外に記録しようとしたときの担当支援役」
が待機していて、その警告を受け止めるイメージです。
実行結果
このプログラムを実行すると、次のようになります。
戦士本部の修行名簿の10番目に戦闘力を登録します。
登録できる範囲をこえています。
修行記録の確認を終えました。この実行結果で注目したいのは、最後のメッセージが表示されていることです。
System.out.println("修行記録の確認を終えました。");この文は、try-catch の後ろに書かれています。
例外は確かに発生しています。
しかし、catch がそれを受け止めたため、try-catch の後ろの処理へ進めています。
| 出力 | なぜ表示されたか |
|---|---|
| 戦士本部の修行名簿の10番目に戦闘力を登録します。 | 例外発生前に実行された |
| 登録できる範囲をこえています。 | catch で表示された |
| 修行記録の確認を終えました。 | catch の後に処理が続いた |
try-catch を使うことで、プログラムは「例外が起きたら即終了」ではなく、「例外を受け止めて、その後の処理へ進む」形になります。
try の中で例外が起きた後の文は実行されない
try ブロックの中には、次の文があります。
System.out.println("10番目に戦闘力9000を登録しました。");しかし、この文は実行されません。
なぜなら、その直前で例外が発生しているからです。
power[10] = 9000;try の中で例外が起きると、その時点で try ブロックの通常処理は中断されます。
その後、対応する catch へ移動します。
つまり、try の中で例外が起きた場合、例外発生行より後ろの文は飛ばされます。
| try 内の処理 | 実行されるか |
|---|---|
| 配列 power を作る | 実行される |
| 10番目に登録します と表示する | 実行される |
| power[10] = 9000; | ここで例外が発生する |
| 10番目に戦闘力9000を登録しました と表示する | 実行されない |
ドラゴンボール風にたとえると、名簿に記録している途中で存在しない欄を指定してしまい、支援役の対応へ切り替わった状態です。
そのため、
「登録しました」
という成功報告には進めません。
ここは、try-catch を理解するうえでとても重要です。
Sample2.java の処理の流れ
今回のプログラムの流れを、順番に整理してみましょう。
| 順番 | 処理 | 実際の動き |
|---|---|---|
| 1 | try に入る | 例外が起きる可能性のある処理を始める |
| 2 | 配列を作る | power = new int[5]; が実行される |
| 3 | 登録開始メッセージを表示 | 戦士本部の修行名簿の10番目に戦闘力を登録します。 |
| 4 | power[10] に代入しようとする | 範囲外なので例外が発生する |
| 5 | try の残りを中断 | 登録成功メッセージは表示されない |
| 6 | catch に移動 | ArrayIndexOutOfBoundsException を受け止める |
| 7 | catch のメッセージを表示 | 登録できる範囲をこえています。 |
| 8 | try-catch の後ろへ進む | 修行記録の確認を終えました。 |
この流れを見ると、try-catch の役割がはっきりします。
try は、危険が起きるかもしれない処理を実行する場所です。
catch は、実際に起きた例外を受け止める場所です。
catch の処理が終わると、try-catch の外側へ進みます。
図:Sample2.java の処理の流れ

この図が示していること
この図は、Sample2.java の処理がどの順番で進むかを表しています。
try の中では、配列を作り、メッセージを表示し、power[10] へ代入しようとします。
しかし、power[10] は範囲外なので、そこで ArrayIndexOutOfBoundsException が発生します。
そのため、try の中にある登録成功メッセージは実行されません。
その後、catch が例外を受け止め、最後に try-catch の後ろの処理へ進みます。
| 図のポイント | 内容 |
|---|---|
| power[10] | 例外が発生する場所 |
| 登録成功メッセージ | 例外発生後なので実行されない |
| catch | 例外を受け止める |
| try-catch の後ろ | catch の後に実行される |
この図から分かることは、try-catch を使っても、try の残りがすべて実行されるわけではないということです。
catch の丸かっこの意味
catch の丸かっこには、どの種類の例外を受け止めるかを書きます。
今回のコードでは、次のようになっています。
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("登録できる範囲をこえています。");
}この部分を分解すると、次のようになります。
| 部分 | 意味 |
|---|---|
| ArrayIndexOutOfBoundsException | 受け止める例外の種類 |
| e | 受け取った例外を入れる変数名 |
| catch の中身 | 例外が起きたときに実行する処理 |
ArrayIndexOutOfBoundsException は、配列の範囲外アクセスが起きたときの例外です。
今回の power[10] = 9000; では、配列の範囲外にアクセスしているため、この例外が発生します。
catch に書かれた例外の種類と、実際に発生した例外の種類が合っているため、catch の処理が実行されます。
ドラゴンボール風にたとえると、catch の丸かっこは「どの種類の任務トラブルを担当するか」を表しています。
| 任務トラブル | Javaの例外 |
|---|---|
| 名簿の範囲外に記録しようとした | ArrayIndexOutOfBoundsException |
| 数字ではない札を数値として読もうとした | NumberFormatException |
| 存在しない巻物を開こうとした | ファイル関連の例外 |
今回の catch は、名簿の範囲外トラブルを担当する支援役です。
catch で受け取るとはどういうことか
例外が起きて、それに対応する catch ブロックが処理を行うことを、catch で受け取ると考えると分かりやすいです。
これは、単にエラーメッセージを表示するだけではありません。
プログラムにとっては、
この種類の問題が起きたら、ここで対応する
という受け皿が用意されている状態です。
今回なら、配列の範囲外アクセスが起きたとき、次の catch が受け止めます。
catch(ArrayIndexOutOfBoundsException e)そして、利用者に分かりやすいメッセージを表示します。
System.out.println("登録できる範囲をこえています。");何も対策していない場合、Javaの長い例外メッセージが表示され、プログラムが途中で終了してしまいます。
しかし、catch があることで、利用者に合わせた説明を表示できます。
| 対応なし | try-catch あり |
|---|---|
| 例外が表示されて途中終了しやすい | catch が受け止めて対応できる |
| 利用者には原因が分かりにくい | 分かりやすいメッセージを出せる |
| 後続処理に進みにくい | catch 後に後続処理へ進める |
ドラゴンボール風に言えば、危険な警報が鳴ったときに、ブルマの解析システムがその内容を分かりやすく言い換えてくれるようなものです。
catch がなかったらどうなるのか
もし Sample2.java に catch がなかった場合、power[10] = 9000; のところで例外が発生し、そのままプログラムは途中で終了します。
つまり、次の最後のメッセージには進めません。
System.out.println("修行記録の確認を終えました。");main メソッドは、プログラムの開始地点です。
main メソッドの中で例外が発生し、それを受け止める catch が見つからない場合、プログラムはそれ以上処理を続けにくくなります。
| 状態 | 結果 |
|---|---|
| catch がない | 例外が発生した場所でプログラムが終了しやすい |
| catch がある | 例外を受け止めて対応できる |
| catch の後ろに処理がある | catch のあとに実行できる |
try-catch は、ただエラー表示を変えるためだけのものではありません。
問題が起きたときに、処理全体をどう続けるかを決めるための大切な仕組みです。
try-catch を使う意味
try-catch を使う意味は、とてもシンプルです。
問題が起きても、そこで終わりにしないためです。
今回のプログラムでは、配列の範囲外アクセスという問題が起きています。
しかし、try-catch を使ったことで、次のような利点が生まれています。
| 利点 | 内容 |
|---|---|
| 問題を受け止められる | ArrayIndexOutOfBoundsException を catch できる |
| 分かりやすいメッセージを出せる | 登録できる範囲をこえています。 と表示できる |
| 後続処理へ進める | 修行記録の確認を終えました。 まで実行できる |
| プログラムが急に終わりにくい | 例外発生時の対応を決められる |
ドラゴンボール風にたとえると、try-catch は任務中の安全装置です。
危険な任務に何の備えもなく向かえば、想定外の事態で流れが止まってしまいます。
しかし、支援役や退避手順を用意しておけば、問題が起きても状況を受け止めて立て直せます。
Javaのプログラムでも、例外が起きそうな処理には try-catch を使うことで、より利用者にやさしい動きにできます。
図:try-catch がある場合とない場合

この図が示していること
この図は、try-catch がない場合とある場合の違いを表しています。
catch がない場合、例外が発生すると、その場で処理が止まりやすくなります。
一方、try-catch がある場合は、catch が例外を受け止め、分かりやすいメッセージを表示したあと、後続処理へ進めます。
| 比較 | catch なし | try-catch あり |
|---|---|---|
| 例外発生時 | その場で止まりやすい | catch が受け止める |
| 利用者への説明 | Javaの例外メッセージが出る | 分かりやすいメッセージを出せる |
| 後続処理 | 進みにくい | 進める |
| プログラムの印象 | 急に止まる | 落ち着いて対応できる |
この図から分かることは、try-catch はプログラムを例外に強くするための安全装置だということです。
try-catch で特に大切なポイント
try-catch を学ぶときは、次の点をしっかり押さえると理解しやすくなります。
| ポイント | 内容 |
|---|---|
| try には危険が起きるかもしれない処理を書く | 配列アクセス、数値変換、ファイル操作など |
| catch には例外が起きたときの対応を書く | メッセージ表示、代替処理、記録など |
| 例外が起きると try の残りは中断される | 例外発生行より後ろの try 内の文は実行されない |
| 例外の種類と catch の種類が合う必要がある | ArrayIndexOutOfBoundsException には対応する catch が必要 |
| catch の後は try-catch の外へ進む | 後続処理を続けられる |
今回の Sample2.java では、try の中で power[10] = 9000; が実行された瞬間に例外が発生しました。
そのため、try 内の成功メッセージは表示されませんでした。
しかし、catch が例外を受け止めたため、最後の確認メッセージまでは進めました。
この流れが、try-catch の基本です。
ドラゴンボール風に try-catch を整理する
try-catch の考え方を、ドラゴンボール風に整理すると次のようになります。
| Javaの考え方 | ドラゴンボール風のイメージ |
|---|---|
| try | 危険の可能性がある任務を進める場所 |
| 例外 | 任務中に起きた想定外のトラブル |
| catch | 支援役がトラブルを受け止める場所 |
| ArrayIndexOutOfBoundsException | 名簿の範囲外に記録しようとした警告 |
| catch の後の処理 | 状況確認後に任務報告へ進む |
Sample2.java では、戦士本部の修行名簿に戦闘力を記録しようとしました。
しかし、5人分しかない名簿の10番目を指定したため、例外が発生しました。
その例外を catch が受け止め、
登録できる範囲をこえています。
と表示しました。
その後、プログラムは
修行記録の確認を終えました。
まで進みました。
このように、try-catch を使うと、問題が起きたときにプログラムがただ止まるのではなく、状況を受け止めて次の処理へ進めるようになります。
この内容で押さえておきたいこと
try-catch は、例外処理の入り口です。
最初から難しく考えすぎる必要はありません。
まずは、次の感覚をつかむことが大切です。
| 考え方 | 内容 |
|---|---|
| try | 危険が起きるかもしれない処理を入れる |
| catch | 実際に起きた例外を受け止める |
| 例外発生後 | try の残りは中断される |
| catch が一致した場合 | catch の処理が実行される |
| catch の後 | try-catch の後ろへ進める |
try-catch を使うと、プログラムは予想外のトラブルに少し強くなります。
もちろん、例外が起きた原因を直すことも大切です。
しかし、実行中にどうしても起こり得る問題に対して、あらかじめ対応を用意しておくことも重要です。
ドラゴンボール風に言えば、危険な任務そのものを避けるだけでなく、もしものときに支援役が受け止められる体制を作っておくことです。
Javaの try-catch は、そのための基本のしくみです。
