Javaのtry-catchによる例外処理の基本とfinallyの使い方を徹底解説
どんなに優れたプログラマーでも、コードにミスを犯すことはあります。タイプミス、予期しないユーザー入力、追跡が難しいさまざまな要因によって、エラーは発生します。
そこで活躍するのが「例外処理」です。質の高いコードには例外ハンドラーが組み込まれており、エラーが発生した際にあらかじめ定義された方法で対応できるようになっています。例外ハンドラーは、プログラムがエラーに遭遇したときにどう振る舞うべきかを指示してくれるため、非常に有用です。
Javaでは、try...catchブロックを使って例外処理を行います。この記事では、例外処理の基礎知識から、try...catchブロックを使った例外の処理方法、さらにfinallyステートメントとの組み合わせまで、実際のコード例を交えながらわかりやすく解説していきます。
Javaにおける例外とは
例外(Exception)とは、プログラムの実行中に発生する予期しないイベントのことです。例外が発生するとプログラムの通常の流れが中断され、最後まで実行されずに停止してしまうことがあります。
例外が発生する原因は多岐にわたります。たとえば、以下のようなものが挙げられます。
- サーバーにアクセスできない
- コードのロジックミスやタイプミス
- 存在しないファイルを開こうとした
- ユーザーからの誤った入力
なお、「エラー(Error)」は例外とは異なる概念です。エラーとは、メモリ不足など、プログラムが回復不能な状態に陥ったことを指します。そのため、エラーは通常、開発者がハンドリングする対象ではありません。
一方、例外はプログラム内で対処可能な問題です。例外が発生すると、例外オブジェクトと呼ばれるオブジェクトが生成されます。このオブジェクトには、例外の名前や発生箇所など、例外に関する情報が格納されています。
それでは、Javaで例外処理の基本を理解したところで、実際にtry...catchステートメントを使って例外を処理する方法を見ていきましょう。
try-catchの基本的な構文
try...catchステートメントは、Javaで例外を処理するために使われます。例外を処理したいコードブロックを、try...catchブロックの中に記述します。
プログラムがtry...catchブロックに到達すると、まずtryブロック内のコードが実行されます。そこで例外が発生した場合には、直ちにcatchブロック内のコードが実行されます。catchブロックは、必ずtryブロックの後に記述しなければなりません。
Javaにおけるtry...catchステートメントの構文は以下の通りです。
try {
// 実行したいコード
} catch (ExceptionType error) {
// 例外が発生したときに実行されるコード
} finally {
// 例外の有無にかかわらず実行されるコード
}
finallyブロックについては後ほど詳しく説明しますので、まずはtry...catchブロックの動作を具体例で確認してみましょう。
try-catchの実践例
ここでは、studentNamesという配列を使うプログラムを作成することを想定します。生徒名が格納されたこの配列から、5番目(インデックス5)の名前をコンソールに出力したいとしましょう。しかし、クラスには6人ではなく5人の生徒しかいません。
存在しない値を参照しようとしているため、このコードはエラーを引き起こします。インデックスは0から始まるため、インデックス5は「6番目の生徒」を意味します。以下は、インデックス5の生徒名を出力しようとするプログラムの例です。
class Main {
public static void main(String[] args) {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
}
}
このコードを実行すると、次のような出力が返されます。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at Main.main(Main.java:4)
ご覧のとおり、存在しない値を参照したため、長いエラーメッセージが出力されてしまいました。
今度は、try...catchブロックを使ってこのエラーを適切に処理してみましょう。エラーが発生したときに「There was an error」というメッセージを出力し、何か問題が起きたことを把握できるようにします。以下のコードでこのタスクを実現できます。
class Main {
public static void main(String[] args) {
try {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
} catch (Exception e) {
System.out.println("There was an error.");
}
}
}
このコードを実行すると、次の出力が返されます。
There was an error.
複数のcatchブロックを使い分ける
さらに、複数のcatchブロックを指定することもできます。これにより、例外の種類ごとに異なる処理を行えるようになります。
先ほどの例ではArrayIndexOutOfBoundsExceptionが発生しました。この特定の例外だけを検出してカスタムメッセージをコンソールに出力しつつ、その他の一般的な例外もテストしたい場合は、複数のcatchステートメントを使用します。
以下は、ArrayIndexOutOfBoundsExceptionと一般的なExceptionの両方を検出し、それぞれにカスタムレスポンスを用意したプログラムの例です。
class Main {
public static void main(String[] args) {
try {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException was raised.");
} catch (Exception e) {
System.out.println("There was an error.");
}
}
}
このプログラムを実行すると、コンソールには次のメッセージが出力されます。
ArrayIndexOutOfBoundsException was raised.
これは、プログラム内でArrayIndexOutOfBoundsExceptionが発生したためです。もし別の種類のエラーが発生した場合は、Exception eのcatchブロック内のコードが実行され、次のメッセージがコンソールに出力されます。
There was an error.
finallyステートメントの使い方
finallyステートメントは、try...catchブロックの実行後に特定のコードブロックを実行するために使用します。finallyブロックは省略可能ですが、定義されていれば必ず実行されます。例外が発生しなかった場合はtryブロックの後に、例外が発生した場合はcatchブロックの後に実行されます。
先ほどの例を使って、finallyステートメントの動作を確認してみましょう。try...catchステートメントの処理が完了したことを示すため、「This block has finished executing」というメッセージをコンソールに出力したいとします。以下のコードで実現できます。
class Main {
public static void main(String[] args) {
try {
String[] studentNames = {"Linda", "Greg", "Ron", "Graham", "Alexis"};
System.out.println(studentNames[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException was raised.");
} catch (Exception e) {
System.out.println("There was an error.");
} finally {
System.out.println("This block of code has finished executing.");
}
}
}
このコードを実行すると、次の出力が返されます。
ArrayIndexOutOfBoundsException was raised. This block of code has finished executing.
ご覧のとおり、先ほどと同様にArrayIndexOutOfBoundsExceptionが発生し、該当するcatchブロック内のコードが実行されました。
この例ではfinallyステートメントを指定しているため、catchブロックの実行後に「This block of code has finished executing」というメッセージが出力されています。このように、finallyブロックを使えば、例外の有無に関係なく、必ず実行したい後処理を確実に行うことができます。
まとめ
try...catchブロックは、Javaで例外を適切に処理(ハンドリング)するために使用されます。tryブロック内のコードが実行され、例外が発生した場合には、該当するcatchブロック内のコードが実行されます。また、finallyステートメントを使えば、例外が発生したかどうかにかかわらず、try...catchブロックの実行後に必ず実行したいコードを記述できます。
この記事では、Javaでtry...catchブロックを使って例外を処理する方法と、finallyブロックの使い方について解説しました。さらに、try...catchブロックとfinallyステートメントを使ってエラーを処理する具体的なコード例も紹介しました。
これで、あなたも自信を持ってJavaの例外処理に取り組めるはずです。ぜひ実際のコードで試してみてください。
-
EclipseでJavaFXをセットアップする方法|Maven依存関係とJARの手動追加を解説
EclipseでJavaFXアプリケーションを開発するためには、あらかじめ環境構築が必要です。この記事では、Maven依存関係を利用する方法と、必要なJARファイルを手動で追加する方法という2つのアプローチをわかりやすく解説します。事前準備セットアップを始める前に、お使いのシステムにEclipseとJava(JDK)が正常にインストールされていることを確認してください。これらが揃っていれば、どちらの方法でもスムーズにJavaFX環境を構築できます。方法1:Maven依存関係を使ったセットアップMavenを利用してJavaFX環境を構築する場合は、まずEclipseで通常のJavaプロジェクトを
-
Java 8 Streamsチュートリアル – コード例で学ぶStream APIの基本と使い方
この記事では、Java 8のStreams(ストリーム)機能について詳しく解説し、さまざまなコード例を交えながらその使い方を紹介します。 Java StreamsはJavaに関数型プログラミングをもたらす強力な機能です。Java 8から導入されたため、それ以前のバージョンを使用している場合は、Java 8以降へのアップグレードが必要です。 なぜJava Streamsを使うべきなのか? Streamsには以下のようなメリットがあります。 少ないコード量で多くを実現できる — ごくわずかな行数のコードで、従来は多くの記述が必要だった処理を簡潔に実装できます。 ラムダ式を活用できる — 使い捨て