
Java入門|例外のクラス構造としくみ
例外の正体はクラスだったとわかると、try-catch の見え方がぐっとクリアになる
これまで、例外は「実行中に起きるトラブル」として見てきました。
この段階でも十分に大事なのですが、さらに一歩進んで中身を見ていくと、例外はただのエラーメッセージではなく、ちゃんとしたクラスのオブジェクトだとわかります。
ここが見えてくると、catch の丸かっこの中にクラス名を書く理由や、なぜ例外ごとに処理を分けられるのかが、すっと理解しやすくなります。
つまり、例外処理は特別な魔法のような仕組みではなく、Java のクラスと継承の仕組みの上に成り立っているのです。
ドラゴンボールの世界でたとえるなら、敵や出来事をひとまとめに「事件」と呼ぶだけではなく、
サイヤ人なのか、ナメック星人なのか、地球人なのか、あるいは特別な能力を持つ存在なのか、
ちゃんと系統ごとに分類されていると考えるとイメージしやすいです。
例外もそれと同じで、すべてがバラバラに存在しているのではなく、親クラスから枝分かれしたクラスの仲間たちとして整理されています。
ここでは、その構造と意味を、ドラゴンボールの世界観に寄せながらやさしく整理していきます。
例外はクラスのオブジェクトである
Java で扱う例外は、単なる文字列や記号ではありません。
Throwable クラスをもとにしたサブクラスのオブジェクトです。
ここがとても大事です。
たとえば、これまで何度か登場してきた ArrayIndexOutOfBoundsException も、例外専用のクラスです。
そして実際に例外が起きたときは、そのクラスのオブジェクトが作られ、catch で受け取られます。
つまり、catch は「エラーっぽい何か」を受け取っているのではなく、
ある例外クラスから作られたオブジェクトを受け取っているわけです。
ドラゴンボール風にたとえると、
「敵が来た」というざっくりした話ではなく、
「サイヤ人という系統に属するベジータが来た」
「ナメック星人という系統に属するピッコロがいる」
というように、ちゃんと所属するクラスの系統があるイメージです。
catch の中で何を受け取っているのか
例外処理のコードでは、次のような形を書きます。
catch(ArrayIndexOutOfBoundsException e) {
...
}この形を分けて見ると、意味は次のようになります。
| 部分 | 意味 |
|---|---|
| ArrayIndexOutOfBoundsException | 受け取りたい例外のクラス |
| e | 受け取った例外オブジェクトを指す変数 |
つまり、catch の丸かっこの中には、
- どの種類の例外を受け取りたいのか
- 受け取った例外をどの名前で扱うのか
この2つが書かれています。
ドラゴンボールの世界で考えるなら、
「この場ではサイヤ人の戦士を受け止める担当を置く」
そして「その戦士を temp ではなく e という名前で扱う」
という感じです。
例外がその catch に一致すると、変数 e はその例外オブジェクトを指すようになります。
だから catch の中で e を使えば、受け取った例外の情報を表示したり、調べたりできます。
受け取れるのは Throwable の仲間だけ
catch で受け取れるのは、何でもよいわけではありません。
Throwable クラスからつながるサブクラスのオブジェクトでなければなりません。
つまり、例外として扱えるのは、例外用の系統に属しているクラスだけです。
これはドラゴンボールでいうと、
天下一武道会の選手受付で、出場資格のある者だけが登録できるようなものです。
誰でも自由にその枠に入れるわけではなく、決められた系統に属している必要があります。
Java でも同じで、catch は「Throwable 系列の仲間」を受け取る場所です。
例外のクラス構造を見てみよう
例外クラスの全体像をつかむには、クラスの親子関係を見るのがいちばん分かりやすいです。
大まかな関係は次のようになっています。
| 階層 | 代表例 | 意味 |
|---|---|---|
| Throwable | すべての土台 | 例外や重大なエラーの大もと |
| Error | OutOfMemoryError など | 通常はプログラム側で対処しない深刻な問題 |
| Exception | IOException など | 一般的な例外処理の対象 |
| RuntimeException | ArrayIndexOutOfBoundsException など | 実行中に起きやすい例外 |
図のイメージとしては、次のように理解すると分かりやすいです。

Throwable
├─ Error
└─ Exception
├─ IOException
└─ RuntimeException
└─ ArrayIndexOutOfBoundsExceptionこの構造を見ると、ArrayIndexOutOfBoundsException は突然出てきた単独の存在ではなく、
- Throwable の仲間であり
- Exception の仲間であり
- RuntimeException の仲間でもある
ということが分かります。
ドラゴンボールでたとえるなら、
悟飯は「個人名」ですが、同時に「地球の戦士」であり、「孫家の一員」でもある、というように、
上位の分類をたどっていけるイメージです。
Throwable は何を表しているのか
Throwable は、例外やエラーを表すクラスの最上位にある存在です。
いわば、問題が起きたことを表す全体の親クラスです。
Java は、実行中に何か異常が起きたとき、その情報を Throwable 系列のオブジェクトとして扱います。
そのため、例外処理の土台を理解するには、この Throwable を出発点として見ることが大切です。
ドラゴンボールの世界でいえば、
「戦いの中で起きる重大な出来事をまとめる大きな分類」がまずあって、
そこから細かい種類に分かれていく感じです。
Error と Exception の違い
Throwable の下には、大きく分けて Error と Exception があります。
この違いはかなり重要です。
| クラス | 意味 | ふつうの考え方 |
|---|---|---|
| Error | プログラムの継続が難しい深刻な問題 | 通常は自分で例外処理しない |
| Exception | プログラムで対処を考える対象 | try-catch で扱うことが多い |
Error は、たとえばシステム資源が足りないなど、プログラムの努力だけではどうにもならないような深刻な問題を表すことがあります。
そのため、学習の基本としては「通常の例外処理で主に扱うのは Exception 側」と覚えると分かりやすいです。
ドラゴンボール風に言えば、
Exception は「戦いの中で起きたトラブルだから、仲間の判断で立て直せるかもしれない問題」、
Error は「惑星そのものが崩壊しかけている」ような、現場だけではどうにもならない事態に近いです。
RuntimeException とは何か
Exception の中には、さらに RuntimeException というグループがあります。
これは、実行中に起こりやすい例外をまとめた系統です。
今回よく出てくる ArrayIndexOutOfBoundsException も、この RuntimeException の仲間です。
つまり、次のようにつながっています。
- Throwable
- Exception
- RuntimeException
- ArrayIndexOutOfBoundsException
このつながりを意識すると、catch でどのクラスを指定するかによって、受け止められる範囲が変わることも理解しやすくなります。
例外情報を出力するサンプル
ここでは、catch で受け取った例外オブジェクトを使って、例外の情報を表示するシンプルな例を見ていきます。
題材はドラゴンボール風に、修行記録の配列に無理な位置を指定してしまう場面にしています。
ファイル名:Sample4.java
class Sample4
{
public static void main(String[] args)
{
try {
int[] power;
power = new int[5];
System.out.println("修行名簿の10番目に戦闘力を記録します。");
power[10] = 9000;
System.out.println("10番目への戦闘力登録が完了しました。");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("記録できる範囲をこえています。");
System.out.println(e + " が発生しました。");
}
System.out.println("修行記録の確認を終えました。");
}
}このプログラムで注目したいところ
このサンプルで特に注目したいのは、catch の中のこの行です。
System.out.println(e + " が発生しました。");ここで使っている e は、catch で受け取った例外オブジェクトです。
そのため、e を表示すると、どんな種類の例外が起きたのかが分かります。
実行結果のイメージは次のようになります。
修行名簿の10番目に戦闘力を記録します。
記録できる範囲をこえています。
java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 5 が発生しました。
修行記録の確認を終えました。出力内容は Java の実行環境によって少し表現が変わることがありますが、
ここで大事なのは、例外オブジェクトを表示すると例外の種類や内容が分かるという点です。
e を表示すると何が分かるのか
catch の中で e を出力すると、次のような情報の手がかりを得られます。
| 分かること | 内容 |
|---|---|
| 例外の種類 | 何の例外が起きたか |
| 詳細情報 | どんな状況だったかの補足 |
| 原因特定の助け | 何を見直せばよいかのヒント |
今回なら、ArrayIndexOutOfBoundsException と表示されることで、
「配列の範囲をこえたアクセスが原因だな」と判断しやすくなります。
これは、戦闘中の警報装置に
「重力装置エラー」
「スカウター読み取り不能」
のように具体的な表示が出るのと同じです。
何が起きたかが分かるから、次の対応を考えやすくなります。
図でクラス構造を整理する

この図は、例外がクラスの階層構造をもっていることと、catch ではその中のどの種類を受け取るのかを指定していることを示しています。
特に、Throwable から Exception、さらに RuntimeException、そして ArrayIndexOutOfBoundsException へとつながる流れを見ることで、例外がクラスの継承関係の中にあることがよく分かります。
この図から読み取れることは、主に次の通りです。
| 分かること | 内容 |
|---|---|
| 例外の正体 | クラスから作られたオブジェクトである |
| 例外の親子関係 | 継承によって整理されている |
| catch の意味 | どの例外クラスを受け取るか指定している |
| e の意味 | 受け取った例外オブジェクトを指している |
図で例外情報の出力も整理する

この図は、発生した例外オブジェクトが catch の変数 e に渡され、それを出力することで例外の情報を見られることを表しています。
コードだけだと e が何者なのか分かりにくいのですが、矢印でつなぐことで、e が実際に発生した例外オブジェクトを指していることが視覚的に理解しやすくなります。
例外の種類ごとに処理を分けられる理由
catch ブロックは1つだけとは限りません。
複数並べることで、例外の種類に応じて処理を分けることができます。
たとえば考え方としては、次のようになります。
catch(ArrayIndexOutOfBoundsException ae) {
配列の範囲外に対する処理
}
catch(IOException ie) {
入出力エラーに対する処理
}これは、例外がクラスとして分類されているからできることです。
ドラゴンボールの世界でたとえると、
サイヤ人が来たときの対応班と、ナメック星の機械トラブル対応班を分けるようなものです。
出来事の種類ごとに担当を分けられるので、処理を整理しやすくなります。
親クラスで広く受け止めることもできる
一方で、細かく分けずに、もっと広い範囲をまとめて受け止めることもできます。
その代表が次のような形です。
catch(Exception e) {
例外全体に対する共通処理
}Exception は多くの例外クラスの親にあたるため、その下のサブクラスに属する例外も受け取れます。
これはドラゴンボールでいうと、
個別の戦士名ではなく「地球の戦士全体を受け止める担当」を置くようなイメージです。
細かい区別はしない代わりに、広い範囲をまとめて扱えます。
ただし、どの例外にどんな対応をしたいのかがはっきりしているなら、できるだけ種類ごとに分けたほうが分かりやすくなることも多いです。
ここで押さえておきたいポイント
ここまでの内容を整理すると、例外のクラス構造について大事なのは次の点です。
| ポイント | 内容 |
|---|---|
| 例外の正体 | Throwable 系列のクラスのオブジェクト |
| catch のクラス名 | 受け取りたい例外の種類を指定している |
| catch の変数 | 受け取った例外オブジェクトを指す |
| 例外の分類 | 継承関係で整理されている |
| 情報の表示 | 変数 e を使うと例外の内容を出力できる |
| 処理の分岐 | 例外クラスごとに catch を分けられる |
| 広い受け止め方 | 親クラスでまとめて受け止めることもできる |
例外処理は、ただエラーを避けるための書き方ではありません。
Java のクラスと継承の仕組みを土台にして、「どんな問題が起きたのか」を分類し、「その種類に応じて受け止める」ための仕組みです。
この見方ができるようになると、catch の書き方が丸暗記ではなくなります。
なぜクラス名を書くのか、なぜ変数 e が使えるのか、なぜ Exception で広く受け止められるのか。
それぞれが自然につながって理解できるようになります。
ドラゴンボールの登場人物たちも、ただ名前が並んでいるだけではなく、親子関係や種族、能力の系統がありますよね。
例外クラスも同じで、バラバラに存在しているのではなく、きちんとした構造の中に位置づけられている仲間たちです。
その構造が見えると、Java の例外処理はぐっと分かりやすくなります。
