
Java入門|finallyで必ず処理を実行する
どんな展開になっても、最後に必要な処理は finally がきちんと守ってくれる
プログラムでは、例外が起きるかどうかだけでなく、最後に必ずしておかなければならない処理があります。
たとえば、作業の後片付け、接続の終了、記録の保存完了の通知などです。
try と catch を使うと、例外が起きたときの対応はできます。
でも、それだけでは「最後に必ず実行したい処理」を確実に書く場所としては少し足りません。
そこで登場するのが finally です。
ドラゴンボールの世界でたとえるなら、修行や戦闘の途中で何が起きたとしても、最後には必ず道具を片づけたり、修行室の装置を停止したり、結界を閉じたりしなければならない場面があります。
途中で予想外のことが起きても、その後始末だけは絶対にしておきたいですよね。
Java の finally も、それと同じです。
例外が起きても、起きなくても、最後に必ず行いたい処理を書くための場所です。
この考え方をしっかりつかんでおくと、より安全で丁寧なプログラムを書けるようになります。
finallyとは何か
finally は、try-catch と組み合わせて使うブロックです。
役割はとてもシンプルで、最後に必ず実行したい処理を書くことです。
基本の形は次のようになります。
try {
例外が起きるかもしれない処理
}
catch(例外のクラス 変数名) {
例外が起きたときの処理
}
finally {
最後に必ず行う処理
}この finally は、例外が起きたかどうかに関係なく実行されます。
つまり、try の処理が順調に終わった場合でも実行されますし、途中で例外が起きて catch が動いた場合でも実行されます。
ドラゴンボール風に言えば、
修行が無事に終わっても、途中で装置トラブルが起きても、最後には必ず重力装置の電源を切る。
それが finally の役目です。
try-catch だけでは足りない場面がある
try-catch を学ぶと、例外が起きたときの対応はできるようになります。
ですが、プログラムには「例外が起きたかどうかに関係なく、最後に共通でやりたいこと」があります。
たとえば、次のような処理です。
| 最後に必要になる処理 | 理由 |
|---|---|
| ファイルを閉じる | 開いたままだと次の処理に影響することがある |
| ネットワーク接続を切る | 接続しっぱなしを防ぐため |
| 使用中の装置を終了する | 資源の無駄や不整合を防ぐため |
| 後片付けのメッセージを出す | 処理の流れを明確にするため |
こうした処理は、例外のあるなしに関係なく必要です。
そのため、catch の中だけに書いてしまうと、例外が起きなかった場合に実行されません。
逆に try の最後に書いてしまうと、途中で例外が起きた場合にはそこまで到達できません。
そこで finally を使います。
サンプルプログラムで見てみよう
ここでは、配列の範囲外アクセスの例外を扱いながら、finally が最後に必ず実行される様子を確認していきます。
ファイル名:Sample3.java
class Sample3
{
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("記録できる範囲をこえています。");
}
finally {
System.out.println("修行室の記録装置を必ず停止します。");
}
System.out.println("修行データの確認を終えました。");
}
}このプログラムの流れ
このプログラムでは、5人分の戦闘力を記録できる配列を作っています。
int[] power;
power = new int[5];配列の要素数は 5 なので、使える添字は 0 から 4 までです。
ところが、そのあとで 10 番目に値を書き込もうとしています。
power[10] = 9000;これは配列の範囲外なので、ArrayIndexOutOfBoundsException が発生します。
そのため、try ブロックの処理はそこで中断されて、対応する catch ブロックへ移動します。
catch では、範囲外であることを知らせるメッセージを表示します。
そしてそのあと、finally が実行されます。
最後に、try-catch-finally の外にある処理も続いて実行されます。
実行結果を見てみよう
このプログラムを実行すると、流れは次のようになります。
修行名簿の10番目に戦闘力を記録します。
記録できる範囲をこえています。
修行室の記録装置を必ず停止します。
修行データの確認を終えました。ここで注目したいのは、finally のメッセージが必ず表示されていることです。
try の中で例外が起きています。
それでも finally の中の処理は飛ばされず、ちゃんと実行されています。
これが finally の最大の特徴です。
finallyはどんなときに実行されるのか
finally は、例外が起きた場合だけに使うものではありません。
例外が起きても、起きなくても実行されます。
整理すると、次のようになります。
| 状況 | try | catch | finally |
|---|---|---|---|
| 例外が起きない | 実行される | 実行されない | 実行される |
| 例外が起きて catch が一致する | 途中で中断される | 実行される | 実行される |
つまり finally は、処理全体の最後に置かれる「後片付け担当」のような存在です。
ドラゴンボール風にたとえるなら、
修行が順調に終わっても、途中でスカウターが壊れても、最後には必ず修行室の扉を閉める。
その「必ずやること」が finally に書かれます。
try・catch・finally の役割の違い
それぞれの役割を並べると、違いが見えやすくなります。
| ブロック | 役割 |
|---|---|
| try | まず処理を実行する場所 |
| catch | 例外が起きたときに受け止めて対応する場所 |
| finally | 最後に必ず実行したい処理を書く場所 |
この3つは、それぞれ担当が違います。
特に finally は、エラー対応そのものを書く場所というより、処理の締めくくりとして必要な作業を書く場所です。
なぜ finally が必要なのか
finally が必要になる理由は、重要な後処理を飛ばさないためです。
たとえば、try の最後に後片付け処理を書いたとします。
すると、途中で例外が起きたときには、その後片付けの行までたどり着けません。
また、catch の中だけに後片付けを書いたとします。
すると、例外が起きなかったときには、その処理は実行されません。
どちらにも偏らず、どんな流れでも必ず最後に実行したい。
そんなときのために finally があるわけです。
これはとても大切な考え方です。
プログラムでは「成功したときの流れ」だけでなく、「失敗したときも後始末できること」が重要だからです。
図で流れを整理する

この図は、例外が起きても起きなくても、最後には finally に処理が集まることを示しています。
特に、try から直接 finally へ進む流れと、catch を経由して finally へ進む流れの両方を描くことで、finally の「必ず実行される」という性質がひと目で分かります。
この図から読み取れることは、次の通りです。
| 分かること | 内容 |
|---|---|
| try の役割 | 最初に通常の処理を試みる |
| catch の役割 | 例外が起きたときに対応する |
| finally の役割 | どの流れでも最後に実行される |
| 実務での意味 | 後片付けや終了処理を確実に行える |
finallyに書くべき処理とは
finally に書くべきなのは、最後に必ず実行しなければ困る処理です。
代表的なものを整理すると、次のようになります。
| 処理の種類 | 例 |
|---|---|
| ファイル関連 | ファイルを閉じる |
| 通信関連 | ネットワーク接続を終了する |
| データベース関連 | 接続を閉じる |
| 装置や資源の利用 | 使用中の資源を解放する |
| 学習用の簡単な例 | 最後の確認メッセージや後片付け表示 |
今回のサンプルでは、学習しやすいように
「修行室の記録装置を必ず停止します。」
というメッセージで表しています。
これは、実務でいうところの「使い終わった資源をきちんと閉じる」ことに対応するイメージです。
catch がなくても finally は大切
finally の価値は、catch があるかどうかだけでは決まりません。
大切なのは、そのメソッドの中で絶対にしておきたい処理を守れることです。
例外処理では、もし現在のメソッド内に対応する catch が見つからなければ、呼び出し元へ戻って catch が探されます。
ですが、その前に「このメソッドの中で必ずやるべきこと」を済ませたい場面があります。
そんなとき、finally に書いておけば、そのメソッドを離れる前に処理できます。
これが finally のとても重要な役目です。
ドラゴンボール風にいえば、
修行を終えたあと、次の場所へ移動する前に、重力装置の停止だけは必ず済ませるようなものです。
誰がその後の状況を引き継ぐとしても、その場の後始末だけはやっておかなければなりません。
Sample3.java から見えてくること
今回の Sample3.java からは、finally について次のことがよく分かります。
| 見えてくること | 内容 |
|---|---|
| 例外が起きても finally は実行される | catch のあとに必ず動く |
| 最後の共通処理をまとめられる | 後片付けを書く場所として使える |
| try や catch と役割が違う | finally は締めくくり担当 |
| 安全なプログラムにつながる | 処理の抜け漏れを防げる |
try と catch だけでも例外対応はできますが、finally が加わることで、プログラム全体がぐっと丁寧になります。
「問題に対応する」だけでなく、「最後に必要なことをやり切る」まで含めて考えられるようになるからです。
この段階でしっかり押さえたいポイント
finally を学ぶときは、次の点をしっかりつかんでおくと理解しやすいです。
| ポイント | 内容 |
|---|---|
| finally の役割 | 最後に必ず行う処理を書く |
| 実行の条件 | 例外の有無に関係なく実行される |
| 書く内容 | 後片付け、終了処理、接続解除など |
| 使う意味 | 重要な処理の実行漏れを防ぐ |
finally は、派手な機能ではありません。
でも、実際のプログラムではとても大切です。
見えにくい部分をきちんと整えるからこそ、安心して動くプログラムになります。
ドラゴンボールの世界でも、強い技や激しい戦いだけではなく、最後に仙豆をしまう、修行室を閉じる、装置の電源を落とすといった締めの動きがあるからこそ、次につながります。
Java の finally も、それと同じように、プログラムを最後まできちんと整えてくれる存在です。
