2023.02.20

予約語

finally句

ここでは、例外発生の有無に関わらず、実行する処理を記述するfinallyブロックについて解説します。

以下のように、記述します。

try {
	実行する処理1;
	実行する処理2;
	   :
	実行する処理n;
}
catch(例外クラス 変数名) {
	例外が発生したときの処理;
	例外が発生したときの処理;
}
finally {
	最後に実行する処理;
}

finallyを使わない場合 その1

まず、finallyブロックが無いtry { ... } catch { ... }についてについて解説します。

ここでは、「最後に実行する処理」をtryブロックとcatchブロックの外に記述します。

try {
	実行する処理1;
	実行する処理2;
	   :
	実行する処理n;
}
catch(例外クラス 変数名) {
	例外が発生したときの処理;
}

最後に実行する処理;

上記のソースコードのtryブロック内の「実行する処理1」から「実行する処理n」のどこかで例外が発生した場合、失敗した処理より後の処理は実行されずに、catchブロック内の「例外が発生したときの処理」に移行します。例えば、「実行する処理2」で例外が発生した場合、「実行する処理3」からの処理は実行されずに、catchブロックの処理に移行します。

このソースコードの場合、tryブロック内で例外が発生しない場合でも、発生した場合でも「最後に実行する処理」が実行されます。

以下は、実際に動作するJavaソースコードです。

FinallySample1.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
// finally説明用のサンプル1
// finallyブロックはありません。

public class FinallySample1 {
	public static void main(String[] args) {
		try {
			int a = 5;	// 割られる数 a
			int b = 0;	// 割る数 b
			int c = a / b;	// 割り算の結果をcに代入

			System.out.println( c );	// 割り算の結果を出力
		}
		catch ( ArithmeticException e ) {
			System.out.println( "エラー(" + e + ")" );	// エラー内容を出力
		}

		// 最後に実行する処理
		System.out.println( "最後に実行する処理" );
	}
}

FinallySample1.javaをコンパイル(ソースコードがANSIの場合)

javac -encoding sjis FinallySample1.java

FinallySample1を実行

java FinallySample1

FinallySample1の出力結果

エラー(java.lang.ArithmeticException: / by zero)
最後に実行する処理

finallyを使わない場合 その2

以下のソースコードの場合はどうでしょうか?

try {
	実行する処理1;
	実行する処理2;
	   :
	実行する処理n;
}
catch(例外クラス 変数名) {
	例外が発生したときの処理;
	return;
}

最後に実行する処理;

tryブロック内で例外が発生しない場合は、tryブロックを抜けて「最後に実行する処理」が実行されます。

例外が発生した場合は、catchブロックに処理が移行します。catchブロック内にreturn文があるので、そのreturn文以降の処理が実行されません。よって、「最後に実行する処理」も実行されません。

以下は、実際に動作するJavaソースコードです。

FinallySample2.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
// finally説明用のサンプル2
// finallyブロックはありません。

public class FinallySample2 {
	public static void main(String[] args) {
		try {
			int a = 5;	// 割られる数 a
			int b = 0;	// 割る数 b
			int c = a / b;	// 割り算の結果をcに代入

			System.out.println( c );	// 割り算の結果を出力
		}
		catch ( ArithmeticException e ) {
			System.out.println( "エラー(" + e + ")" );	// エラー内容を出力

			// mainメソッドを抜ける
			return;
		}

		// 最後に実行する処理
		System.out.println( "最後に実行する処理" );
	}
}

FinallySample2.javaをコンパイル(ソースコードがANSIの場合)

javac -encoding sjis FinallySample2.java

FinallySample2を実行

java FinallySample2

FinallySample2の出力結果

エラー(java.lang.ArithmeticException: / by zero)

finallyを使わない場合 その3

以下は、あまり良くないソースコードの書き方で、tryブロックとcatchブロックの中の両方に「最後に実行する処理」を記述したものです。

この書き方の場合、例外が発生しなくても発生しても「最後に実行する処理」が実行されますが、同じ処理を複数回記述しているので、良いとはいえません。

try {
	実行する処理1;
	実行する処理2;
	   :
	実行する処理n;
	最後に実行する処理;
}
catch(例外クラス 変数名) {
	例外が発生したときの処理;
	最後に実行する処理;
	return;
}

以下は、実際に動作するJavaソースコードです。

FinallySample3.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
// finally説明用のサンプル3
// finallyブロックはありません。

public class FinallySample3 {
	public static void main(String[] args) {
		try {
			int a = 5;	// 割られる数 a
			int b = 0;	// 割る数 b
			int c = a / b;	// 割り算の結果をcに代入

			System.out.println( c );	// 割り算の結果を出力

			// 最後に実行する処理
			System.out.println( "最後に実行する処理" );
		}
		catch ( ArithmeticException e ) {
			System.out.println( "エラー(" + e + ")" );	// エラー内容を出力

			// 最後に実行する処理
			System.out.println( "最後に実行する処理" );

			// mainメソッドを抜ける
			return;
		}
	}
}

FinallySample3.javaをコンパイル(ソースコードがANSIの場合)

javac -encoding sjis FinallySample3.java

FinallySample3を実行

java FinallySample3

FinallySample3の出力結果

エラー(java.lang.ArithmeticException: / by zero)
最後に実行する処理

finallyを使う

次に、finallyブロックを記述したtry { ... } catch { ... } finally { ... }についてについて解説します。

ここでは、「最後に実行する処理」finallyブロックに記述します。

try {
	実行する処理1;
	実行する処理2;
	   :
	実行する処理n;
}
catch(例外クラス 変数名) {
	例外が発生したときの処理;
	例外が発生したときの処理;
	return;
}
finally {
	最後に実行する処理;
}

このソースコードは、tryブロックで例外の発生の有無に関わらす「最後に実行する処理」が実行されます。

catchブロックの中に、return文があるのでメソッドを抜けます。finallyブロックの中の処理は、このreturn文に関係なく実行されます。

以下は、実際に動作するJavaソースコードです。

FinallySample4.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
// finally説明用のサンプル4
// finallyブロックで「最後に実行する処理」を実行します。

public class FinallySample4 {
	public static void main(String[] args) {
		try {
			int a = 5;	// 割られる数 a
			int b = 0;	// 割る数 b
			int c = a / b;	// 割り算の結果をcに代入

			System.out.println( c );	// 割り算の結果を出力
		}
		catch ( ArithmeticException e ) {
			System.out.println( "エラー(" + e + ")" );	// エラー内容を出力

			// mainメソッドを抜ける
			return;
		}
		finally {
			// 最後に実行する処理
			System.out.println( "最後に実行する処理" );
		}
	}
}

FinallySample4.javaをコンパイル(ソースコードがANSIの場合)

javac -encoding sjis FinallySample4.java

FinallySample4を実行

java FinallySample4

FinallySample4の出力結果

エラー(java.lang.ArithmeticException: / by zero)
最後に実行する処理

finallyでやってはいけないこと

finallyブロック内で、制御が外へ移行する処理が記述できません。

以下がその例です。

	finally {
		return;
	}
	finally {
		break;
	}
	finally {
		continue;
	}
	finally {
		System.exit( 0 );
	}

以下は、実際に動作するJavaソースコードです。

finallyブロックの中にreturn文を記述している例です。

FinallySample5.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
// finally説明用のサンプル5
// finallyブロックにreturn文を記述しています。(お勧めしません)

public class FinallySample5 {
	private static String FinallyTest()
	{

		try {
			int a = 5;	// 割られる数 a
			int b = 0;	// 割る数 b
			int c = a / b;	// 割り算の結果をcに代入

			System.out.println( c );	// 割り算の結果を出力
		}
		catch ( ArithmeticException e ) {
			System.out.println( "エラー(" + e + ")" );	// エラー内容を出力

			// メソッドを抜ける
			return "catchブロックのreturn実行";
		}
		finally {
			// 最後に実行する処理
			return "finallyブロックのreturn実行";
		}
	}


	public static void main(String[] args) {
		String ans = FinallyTest();

		// 結果をコンソール出力
		System.out.println( ans );
	}
}

FinallySample5.javaをコンパイル(ソースコードがANSIの場合)

javac -encoding sjis FinallySample5.java

FinallySample5を実行

java FinallySample5

FinallySample5の出力結果

エラー(java.lang.ArithmeticException: / by zero)
finallyブロックのreturn実行

catchブロック内のreturn文ではなく、finallyブロック内のreturn文の値がメソッド戻り値になっています。

finallyブロック内でreturn文を使うことは、分かりにくいソースコードになるためお勧めしません。

関連コンテンツ

メソッドを抜けるときに使用するreturn文について説明しています。

2020.03.20

繰り返し処理(ループ)から強制的に抜けかたについて解説しています。

2017.07.14

繰り返し処理を制御するための機能の1つである「continue」について詳しく解説しています。

2019.10.16

Javaのプログラムを書いてみませんか?プログラムの書き方をくわしく説明しています。

2020.03.23

プログラミング、ITに関する用語をまとめています。

2022.10.17

変数やクラスに格納されている値をコンソール出力する方法は?

2020.03.23

プログラムの最初に実行されるメソッドは?

2022.12.13

プログラミングで使う変数って何?

2020.03.23

「Javaソースコード」から実行可能な「オブジェクトコード」に変換する方法をくわしく説明しています。

2020.03.23

プログラミング言語とは?種類や特徴について説明しています。

2022.08.03

メソッドの定義方法を詳しく解説しています。Javaのサンプルソースコードを使った説明もあります。

2020.03.23

広告