例外処理

Java基礎 11

1.本章での学習項目

本章ではプログラム実行時において例外的に発生したエラーを、適切に対処するための例外処理方法について学習します。

2.本章の講義

本章で学習する内容を動画としてまとめたものです。最初に一通り見終わった後で、学習に入るようにしてください。

講義:例外処理

3.例外処理とは

プログラミングでは、コンパイルエラーがなく、無事にコンパイルできたとしても、そのプログラムの実行時にエラーが発生することは日常茶飯事です。

こういった実行時エラーはそのまま放っておくと、急にシステムがダウンしたり、意味のわからないエラーメッセージが出てきたりと大変不安定で障害の多いシステムとなってしまいます。

実行時のエラーには、例えば、以下のようなものがあります。

  • あるファイルのデータを読み込もうとしたが、指定されたファイルが見つからなかった。
  • データベースに接続しようとしたが、データベースの接続認証で失敗した。
  • “Hello”という文字列をint型に変換しようとした。

こういったエラーは、構文エラーのようにコンパイルエラーが発生するわけでなく、実行したときに初めて発生するエラーです。
これらのエラーのことを「例外」と呼び、例外が発生したときに適切に処理を行うことを「例外処理」と呼びます。
Javaでは、例外を扱うために例外クラスが用意されており、エラーが発生すると例外クラスからオブジェクトが生成され、そのオブジェクトにエラー情報を持たせます。
例外処理とは、この例外クラスから生成されたオブジェクトの処理方法を言います。

3.1.例外の種類

それでは、実行時に発生する例外の種類をまず確認しておきましょう。

  1. プログラム処理例外(実行時例外)

    プログラム処理例外とは、プログラムを実行するときに発生する例外で、例えば、以下のようなものがあります。

    • データベース接続時エラー
    • ファイル書き込みエラー
    • 型変換エラー
    • 0除算(0の割り算)エラー

    プログラム処理例外は、Javaの仕様で対象の例外クラスがあらかじめ定義されています。
    処理例外ケースが発生した場合には、その例外クラスを使用してオブジェクトが生成されるようになっています。

  2. システム例外

    システム例外とは、システム的な障害で、例えば、停電やユーザが強制的に電源を落としたりなどのときに発生する例外で、JVMやOSに依存するエラーです。
    正常なプログラムでも発生する可能性があり、また発生後にプログラム内で例外処理を行うには難しく、通常、例外処理対応はしません。
  3. 業務例外

    業務例外とは、業務の仕様上の例外で、Javaの標準で決められた例外ではなく、システムを利用するユーザの業務仕様により決めた例外です。
    例えば、「マイナスの数値を入力されたらエラー」と設定したり、ログインの機能の中でいくつものJava標準の例外が発生する可能性があっても一つの「ログインエラー」と設定したりするような場合です。

3.2.例外クラスの種類

それでは、例外クラスの種類を確認しましょう。
例外クラスは、多くの種類がありますが、以下のように分類できます。


exception1

全ての例外クラスは、Throwableクラスを継承しています。
Throwableクラスは、以下の2つの子クラスに継承されています。
全てのクラスは、この2つの子クラスのどちらかを継承して定義されていることになります。

  1. Errorクラス

    Errorクラスは、JVMのエラーなど何らか致命的なエラーが発生した場合に例外オブジェクトがこのErrorクラスから生成されます。
    ただ、こういった致命的エラーが発生した場合、例外処理を行おうにも実行自体ができないので、通常、Errorクラスオブジェクトの例外処理は行いません。
  2. Exceptionクラス

    Exceptionクラスは、通常のプログラム実行時に発生するエラーです。
    このクラスの子クラスは多数存在し、色々な処理でエラーとして例外クラスのオブジェクトを生成します。

    Exceptionクラスの子クラスに、RuntimeExceptionクラスというクラスがありますが、このRuntimeExceptionクラスの子クラスとして定義されている例外は、例外処理が必須ではないため、書いても書かなくても良いことになっています。
    例えば、0除算のエラーや型変換のエラーなどが該当します。これらは、例外処理を記述しなくもプログラムロジックで回避することが可能ですので、例外処理を記述しなくてもコンパイルエラーにはなりません。

    Exceptionクラスの子クラスでRuntimeException以外の子クラスは、全て例外処理は必須となります。
    例えば、データベースとの接続やファイルへのデータの書き込みなどは、エラーが発生しやすく、またロジックで回避することは困難であるため、必ず例外処理を記述する必要があります。
    例外処理を記述しないとコンパイルエラーになるので、気をつけましょう。その他、例外処理が必須である例外クラスとしては、開発者が独自で定義した独自例外クラスも同様になります。

3.3.例外発生

例外が発生したときのエラー表示について確認してみましょう。

以下は、0除算エラーで発生するArithmeticExceptionという例外のサンプルソースです。

MyExceptionSample.java
public class MyExceptionSample {

	public static void main(String[] args) {
		// 0除算のためエラー
		int x = 5 / 0;

		System.out.println("0除算のためエラー");
	}
}

このプログラムを実行すると、以下のようなエラーがコンソールに出力されます。

実行結果
Exception in thread "main" java.lang.ArithmeticException:/by zero
at MyExceptionSample.main(MyExceptionSample.java:5)

実行結果1行目で、発生した例外が「java.lang.ArithmeticException」であり、「by zero」で0除算によるエラーであることを示しています。
また、実行結果2行目の「MyExceptionSample.java:5」で例外発生した場所がソースの5行目であることが分かります。
例外が発生し、上記のようなエラーがコンソールに出力される場合、プログラムの実行が5行目で中断されているため、その次の「0除算のためエラー」という文字列は出力されません。

このようなエラーメッセージは上述したように、どこで、どのようなエラーが発生しているのかを詳細に示しています。
エラーメッセージをきちんと読み解くことが、バグ改修の精度やスピードの向上に繋がっていきます。
そのため、エラーメッセージは、必ず自身でしっかりと読み解くクセをつけましょう。

4.try・・catch文

それでは、実際に例外処理の方法について学習しましょう。
例外処理については、try・・catchという構文で対応することが基本になります。

try・・catch文の構文は、以下のとおりになります。
例外処理を行いたい例外が発生する可能性がある箇所にtry{}で括って、そのtry{}の下にcatchを記述することで、例外が発生した場合は、catchに制御を移すようにします。
catchのところにエラーメッセージ出力など例外発生時に行いたい処理を記述します。

try {
	//例外が発生する可能性のある処理

} catch (例外クラス名 e(例外オブジェクトの参照変数名)) {
	// 例外を受け止めるcatchブロック
	// try{}の中で発生した例外を該当の例外クラスのオブジェクトeで受け止めます。
	// ここに例外発生時に行いたい処理(エラーメッセージ出力など)を記述します。
}


exception2

また、以下のようにcatch文を複数記述することも可能です。
try{}の中で複数例外が発生する可能性がある場合、また複数例外の処理を行いたい場合に、以下のように記述します。
各例外の該当例外クラスのところでcatchされます。

このような記述をすると、例外処理内容を各例外に合わせて変更することができます。

try {
	// 例外1が発生する可能性のある処理
	// 例外2が発生する可能性のある処理
	// 例外3が発生する可能性のある処理

} catch (例外1クラス名 e(例外1オブジェクトの参照変数名)) {
	// 例外1を受け止めるcatchブロック
	// try{}の中で発生した例外1を該当の例外クラスのオブジェクトeで受け止めます。
	// ここに例外発生時に行いたい処理(エラーメッセージ出力など)を記述します。

} catch (例外2クラス名 e(例外2オブジェクトの参照変数名)) {
	// 例外2を受け止めるcatchブロック
	// try{}の中で発生した例外2を該当の例外クラスのオブジェクトeで受け止めます。
	// ここに例外発生時に行いたい処理(エラーメッセージ出力など)を記述します。

} catch (例外3クラス名 e(例外3オブジェクトの参照変数名)) {
	// 例外3を受け止めるcatchブロック
	// try{}の中で発生した例外3を該当の例外クラスのオブジェクトeで受け止めます。
	// ここに例外発生時に行いたい処理(エラーメッセージ出力など)を記述します。
}

4.1.finallyブロック

finallyブロックは、例外が発生するしないに関係無く、常に実行されるブロックです。

try {
	// 例外が発生する可能性のある処理

} catch (例外クラス 参照型変数) {
	// 例外が発生したときの処理

} finally {
	// 例外が発生した場合もしなかった場合も実行する処理

}


exception3

4.2.例外処理のサンプルソース

それでは、例外処理のサンプルソースを確認してみましょう。
以下は、int型の0除算でArithmeticException例外が発生するサンプルソースです。

MyException1.java
public class MyException1 {

	public static void main(String[] args) {
		int a, b, c;
		a = 3;
		b = 0;

		// 変数aを変数b(値は0)で割ると例外が発生します
		c = a / b;

		System.out.println("正常終了");
	}
}

実行すると、コンソール画面に以下のような例外のメッセージが表示されます。

実行結果
Exception in thread "main" java.lang.ArithmeticException:/by zero
at MyException1.main(MyException1.java:9)

例外が発生すると、Java仮想マシンは、その例外に対するcatch文を探します。
もし、そのメソッド内に見つからない場合は、そのメソッドを呼び出したメソッドから、catchブロックを探します。
最終的にmainメソッドでも見つからない場合、プログラムは強制的に終了し、画面に例外が発生したことを知らせるメッセージが表示されます。

それでは、上記のプログラム「MyException1」に例外処理を追加してみましょう。以下がサンプルソースです。

MyException1.java
public class MyException1 {

	public static void main(String[] args) {
		int a, b, c;
		a = 3;
		b = 0;

		try {
			// 変数aを変数b(値は0)で割ると例外が発生します
			c = a / b;

		} catch (ArithmeticException e) {
			// 例外が発生すると実行します
			System.out.println("例外発生");
			return;

		} finally {
			// 例外が発生してもしなくても実行します
			System.out.println("finallyです。");
		}
		// 例外が発生しなければ実行します
		System.out.println("正常終了");
	}
}

例外処理を正しく行えば、プログラムが強制的に終了することはありません。
実行すると、画面に「例外発生」と表示して、return文により、mainメソッドが終了していることがわかります。
return文でmainメソッドが終了する前に、finally文が実行され、「finallyです。」が表示されます。

実行結果
例外発生
finallyです。

try・・catch文の使い方は理解できたでしょうか。例外処理は、重要な文法ですので、よく理解するようにしましょう。

5.throw文

throwという構文を使って、意図的に例外を発生させることができます。
投げられた例外は、その例外を受け取れるcatchブロックで処理します。
throw文を利用するとtryの中で強制的にcatchへ制御を移行させることもできます。

以下がthrow文の書式です。

throw new 例外クラスのコンストラクタ();

すでに例外クラスのインスタンスが参照型変数にセットされている場合は、以下の構文になります。

throw 例外クラス型参照変数;

以下がサンプルソースです。実行すると、ArithmeticException例外が発生していることが分かります。

MyException2.java
public class MyException2 {

	public static void main(String[] args) {
		int a = 0;

		if (a == 0) {
			// 意図的に ArithmeticException 例外を発生させます
			throw new ArithmeticException();
		}
	}
}
実行結果
Exception in thread "main" java.lang.ArithmeticException
at MyException2.main(MyException2.java:8)

これは例でありArithmeticExceptionはRuntimeExceptionクラスの子クラスなので、try…​catchの記述は強制されません。
以下のように、tryブロック内で例外を発生させて、一致する例外クラスが指定されているcatchブロックに制御を移すこともできます。

MyException2.java
try {
	例外が発生する可能性がある処理1
	if (条件式) {
		// 条件式がtrueならthrowします
		throw new 例外クラス A();
	}
		// throwされるとcatchへ飛ぶのでここは、実行されません
		例外が発生する可能性がある処理2;

	} catch (例外クラス A 参照変数) {
		例外 A が発生したときの処理;
	}
		・
		・
		・
}

6.オリジナル例外クラス

Javaの標準例外クラスは数多くあります。APIドキュメントで、JDKパッケージのクラスがどのようなときにどのような例外が発生するのかを調べることができます。
メソッドが投げる例外の種類は、メソッドの宣言を調べ、その例外クラスの詳しい内容は、Exceptionクラスの子クラスを調べます。

もし、目的に合う例外クラスが存在しない場合は、Exceptionクラスを継承したオリジナル例外クラスを定義できます。
例外クラスも、Exceptionクラスを継承している以外は、他のクラスと全く同じです。
必要であれば、コンストラクタやメソッドを追加できます。

以下がサンプルソースです。Exceptionクラスを継承して、MyErrExceptionクラスを定義しています。
また、引数なしのコンストラクタも定義されています。

MyErrException.java
public class MyErrException extends Exception {
	MyErrException() {
		System.out.println("オリジナル例外");
	}
}

オリジナル例外クラスは、throw文で例外を発生させ、try・・catchの処理ができます。
以下がサンプルソースです。

MyException3.java
public class MyException3 {

	public static void main(String[] args) {
		int a = 0;

		if (a == 0) {
			// 例外処理は省略できない。
			try {
				throw new MyErrException();

			} catch (MyErrException e) {
				System.out.println("MyErrException発生");
			}
		}
	}
}
実行結果
オリジナル例外
MyErrException発生

オリジナル例外クラスは、RuntimeExceptionクラスの子クラスではないので、例外処理は省略できません。
省略するとコンパイルエラーになりますので、注意しましょう。

7.throws文

定義したメソッドが例外を発生する可能性がある場合、その例外クラスをメソッドの宣言に明示的に記述できます。
メソッドの中でthrowsで明示した例外が発生すると、そのメソッドの処理が終了し、呼び出し元に制御が移ります。
このとき、発生した例外オブジェクトは呼び出し元にそのまま引き渡されます。
よって、throwsを定義したときは例外処理を呼び出し元で行うことができます。
throws文は明示的に宣言することで、メソッドで発生する例外の種類がすぐに分かるため、利用するときに例外処理を適切に行うことができます。

メソッド定義で例外の宣言をする構文は、throws文です。以下が書式になります。

戻り値のデータ型 メソッド名() throws 例外クラス名 {
}

以下がサンプルソースです。myTestメソッドでArithmeticExceptionの例外が発生することを明示しています。
このメソッドを利用するときにこの例外が発生した場合は、ArithmeticExceptionクラスのオブジェクトが引き渡されてきます。

void myTest() throws ArithmeticException {
	int a, b, c;
	a=3;
	b=0;

	// ArithmeticException例外が発生
	c = a / b;
}

複数の例外を返す可能性がある場合は、throwsの後ろの例外クラスをカンマで区切って記述していきます。

void myTest() throws ArithmeticException, NumberFormatException {
	int a, b, c, d;
	a=3;
	b=0;

	// NumberFormatException例外の発生の可能性あり
	d = Integer.parseInt(args[0]);

	// ArithmeticException例外が発生
	c = a / b * d;
}


exception4

ArithmeticExceptionクラスやNumberFormatExceptionクラスは、RuntimeExceptionの子クラスなので、サンプルのmyTestメソッドの呼び出すときに例外処理は強制されません。
しかし、RuntimeException以外の例外クラスをthrows宣言しているメソッドを呼び出す場合は、例外処理を実装しないとコンパイルエラーになりますので、注意しましょう。

以下のサンプルは、myErrTestメソッドがオリジナルMyErrException例外を発生する可能性があることを宣言しています。
実行すると、myErrTestメソッドが呼ばれます。このmyErrTestでオリジナル例外を発生させて、呼び出し元で例外処理を行っています。

MyException4.java
public class MyException4 {

	public static void main(String[] args) {
		int a = 0;

		if (a == 0) {
			// 例外処理は省略できません
			try {
				// MyErrException 例外が発生する可能性あり
				myErrTest();

			} catch (MyErrException e) {
				System.out.println("MyErrException発生");
			}
		}
	}

	static void myErrTest() throws MyErrException {
		throw new MyErrException();
	}
}
実行結果
オリジナル例外
MyErrException発生

このように、throws文は例外が発生したところで例外処理をせずにメソッドの呼び出し元に例外処理を任せてしまう方法です。
throws文を使うことで、呼び出し元でどのような例外処理を行うのかを決めることができるようになります。

これにより、呼び出し元のクラスで様々なクラスを呼び出す場合に、例外処理を共通化したり、呼び出したクラスで発生し得る例外の処理の漏れを未然に防ぐことも可能になります。

また、throws文は、throw文と単語は似ていますが、意図的に例外を発生させるthrow文とは全く役割が異なりますので、混同しないようにしましょう。

8.例外ハンドラの検索

try・・catch文のcatchの中に記述される例外発生時の処理内容(エラーメッセージ出力、エラーログ書き出し、エラーメッセージ送信など)を「例外ハンドラ」と呼びます。
例外が発生すると、該当する例外クラスが記述されているcatch文を検索します。

例えば、ArithmeticException例外が発生した場合は、以下のようなcatch文でキャッチすることができます。

} catch (ArithmeticException e) {
	// 例外ハンドラの記述
}

また、Exceptionクラスは、ArithmeticExceptionの親クラスにあたりますので、ArithmeticExceptionの例外が発生した場合は、Exceptionクラスでもキャッチできます。

} catch (Exception e) {
	// 例外ハンドラの記述
}

複数のcatch文で記述する場合、先にExceptionクラスのcatch文を記述してはいけません。
Exceptionクラスが全ての例外がキャッチされてしまうため、それ以下のcatch文で処理することができずコンパイルエラーになりますので、注意しましょう。

// 全ての例外をキャッチして、例外処理
} catch (Exception e) {

// Exceptionでキャッチされ実行されないため、コンパイルエラー
} catch (ArithmeticException e) {

}

よって、複数のcatch文を記述する場合には、以下のように親クラスの記述は、後にする必要があります。

// ArithmeticExceptionの例外処理
} catch (ArithmeticException e) {

// ArithmeticException以外のExceptionの例外処理
} catch (Exception e) {

}

throws文を明示的に記述せずメソッド内で例外が発生し、catchされていない場合、呼び出し側に例外ハンドラを探しに行きます。
以下がサンプルソースです。

MyException5.java
public class MyException5 {

	public static void main(String[] args) {
		// 例外がcatchされない場合、プログラムは強制終了し、例外が画面に表示されます
		// myTest1メソッドを呼び出します
		myTest1();
	}

	static void myTest1() {
		// myTest1メソッドではmyTest2メソッドを呼び出します
		myTest2();
	}

	static void myTest2() {
		// myTest2メソッドではmyTest3メソッドを呼び出します
		myTest3();
	}

	static void myTest3() {
		int a, b, c;
		a = 3;
		b = 0;

		// 例外は発生したメソッド内で catch しないと、呼び出した側へ渡されます
		// myTest3メソッドでは例外が発生します
		c = a / b;
	}
}
実行結果
Exception in thread "main" java.lang.ArithmeticExcetpin: / by zero
	at MyException5.myTest3(MyException5.java:26)
	at MyException5.myTest2(MyException5.java:16)
	at MyException5.myTest1(MyException5.java:11)
	at MyException5.main(MyException5.java:6)

発生した例外は、Java仮想マシンに渡る前に、どこかでcatchすればよく、最悪mainメソッド内でもOKとなります。
以下のサンプルは、上記「MyException5」クラスのmainメソッドにcatch処理を追加した例です。

MyException5.java
public class MyException5 {

	public static void main(String[] args) {
		try {
			// myTest3メソッドの例外がここまでスローされて
			myTest1();

		// ここで例外をcatchします
		} catch (ArithmeticException e) {
			System.out.println("例外発生");
			return;
		}
		System.out.println("正常終了");
	}

	static void myTest1() {
		// myTest1メソッドでは例外をcatchしません
		myTest2();
	}

	static void myTest2() {
		// myTest2メソッドでは例外をcatchしません
		myTest3();
	}

	static void myTest3() {
		int a, b, c;
		a = 3;
		b = 0;

		// 例外が発生しますが、catchしません
		c = a / b;
	}
}

例外は、mainメソッドでcatchされ、画面には「例外発生」と表示しています。

実行結果
例外発生

このように、throws文がなくても、例外は呼び出し元に渡されていきますが、throws文で説明したように、メソッドにthrowsの明示がない場合、どんな例外が発生するかがわかりにくくなります。
そのため、利用する側で例外処理が抜けてしまうことがありますので、例外を呼び出し側で処理してほしい意図がある場合は、throws文を使用するようにしましょう。

9.練習問題1

9.1.問題1

以下のプログラムは、IntegerクラスのparseIntメソッドで文字を数字に変換していますが、変換できない場合にNumberFormatException例外が発生します。
数字以外の文字列が引き渡された場合には、画面に「数字を入力してください」と表示するように例外処理を追加してください。

※ コマンドライン引数で値を引き渡して実行しましょう。>

ExceptionMondai1.java
public class ExceptionMondai1 {

	public static void main(String[] args) {

		// コマンドライン引数で引き渡された値をint型に変換
		int num = Integer.parseInt(args[0]);

		// 10倍に計算
		int kekka = num * 10;

		// 10倍した結果を出力
		System.out.println(num + "の10倍は、" + kekka + "です。");
	}
}

ExceptionMondai1.java
public class ExceptionMondai1 {

	public static void main(String[] args) {

		// 例外が発生する可能性があるため、例外処理
		try {
			// コマンドライン引数で引き渡された値をint型に変換
			int num = Integer.parseInt(args[0]);

			// 10倍計算
			int kekka = num * 10;

			// 10倍した結果を出力
			System.out.println(num + "の10倍は、" + kekka + "です。");

		} catch (NumberFormatException e) {
			// 例外発生時のメッセージ出力
			System.out.println("数字を入力してください。");
		}
	}
}

コマンドライン引数で引き渡された値を「args[0]」で取得し、その値をIntegerクラスのparseIntメソッドでint型に変換しています。
この処理で、コマンドライン引数が数字でなかった場合、int型の変換ができずにNumberFormatExceptionという例外が発生します。
まず、最初に例外処理を追記する前に、NumberFormatExceptionが発生することを確認すると良いでしょう。

例外が発生する場所を囲むように、try・・catch文を記述します。
catch文では、NumberFormatExceptionでcatchするように定義し、その中の処理で例外メッセージを出力します。

9.2.問題2

問題1のプログラムにint型に変換した数字が1000以上の場合、オリジナル例外クラスMyErrException1の例外が発生するようにif文とthrow文を追記してください。
また、MyErrException1の例外発生時には、画面に「1000未満の数字を入力してください」と表示するように例外処理も追加してください。
※ コマンドライン引数で値を引き渡して実行しましょう。>

※ 以下の「ExceptionMondai1」クラスのソースには、問題1のプログラムで記述する例外処理は記述しておりません。
あくまで追記位置を示すためのものとなっております。

MyErrException1.java
public class MyErrException1 extends Exception { // オリジナル例外クラスの定義
}
ExceptionMondai1.java
public class ExceptionMondai1 {

	public static void main(String[] args) {

		// コマンドライン引数で引き渡された値をint型に変換
		int num = Integer.parseInt(args[0]);

		/* ここにif文とthrow文を追記 */

		// 10倍に計算
		int kekka = num * 10;

		System.out.println(num + "の10倍は、" + kekka + "です。");
	}
}

ExceptionMondai1.java
public class ExceptionMondai1 {

	public static void main(String[] args) {

		// 例外が発生する可能性があるため、例外処理
		try {
			// コマンドライン引数で引き渡された値をint型に変換
			int num = Integer.parseInt(args[0]);

			// 引数の値が1000以上の場合
			if (num >= 1000) {
					// オリジナル例外MyErrException1を発生
					throw new MyErrException1();
			}

			// 10倍計算
			int kekka = num * 10;

			// 10倍した結果を出力
			System.out.println(num + "の10倍は、" + kekka + "です。");

		// int型への変換の例外処理
		} catch (NumberFormatException e) {
			// 例外発生時のメッセージ出力
			System.out.println("数字を入力してください。");

		// 1000以上のときの例外処理
		} catch (MyErrException1 e) {
			// 例外発生時のメッセージ出力
			System.out.println("1000未満の数字を入力してください。");
		}
	}
}

コマンドライン引数で引き渡された値をint型に変換した後に、その値が1000以上かをif文で判定します。
1000以上の場合、オリジナルで定義した例外MyErrException1の例外をthrow文で発生させます。
例外が発生すると、それ以降の10倍計算や出力処理は実行されずに、catch文に処理の制御が移ります。

問題1で記述したNumberFormatExceptionの例外処理もありますので、catch文を並べてそれぞれの例外がcatchできるように記述するようにしましょう。

10.練習問題2

練習問題1のように、コマンドライン引数の値が数字でない場合、「数字を入力してください。」、1000以上の場合、「1000未満の数字を入力してください」と画面に表示するようにプログラムを作成しましょう。

10.1.問題1

CalcクラスのgetBaisuメソッドに「引数の値が1000以上だったら、MyErrException2例外をthrow文で発生させる」処理を追加してください。
ただし、「ここに追記」以外の個所を修正してはいけません。

MyErrException2.java
public class MyErrException2 extends Exception {
}
Calc.java
public class Calc {

	public String getBaisu(String str) /* ここに追記(throws文) */ {
		// 引数で渡された値をint型に変換
		int num = Integer.parseInt(str);

		/*  ここに追記(1000以上だったら、MyErrException2例外をthrow文で発生) */

		// 引数で渡された値を10倍にして戻す
		return String.valueOf(num * 10);
	}
}

※この問題の解答は掲載しておりません。Tech Fun ITスクールのJava研修では、講師が丁寧に解説しています。

10.2.問題2

問題1で作成したCalcクラスのgetBaisuメソッドを呼び出す、「ExceptionMondai2」クラスを作成してください。
なお、getBaisuメソッド呼び出し時に発生する例外については、以下のように処理してください。
・NumberFormatExceptionが発生した場合、「数字を入力してください。」とコンソール出力する。
・MyErrException2が発生した場合、「1000未満の数字を入力してください」とコンソール出力する。

ExceptionMondai2.java
public class ExceptionMondai2 {
	// 引数で渡された値を10倍計算するメソッド
	public static void main(String[] args) {
		String str = "";

		Calc calc = new Calc();

		// getBaisuメソッドの呼び出し処理
		str = args[0] + "の10倍は、" + calc.getBaisu(args[0]) + "です。";

		System.out.println(str);
	}

}

※この問題の解答は掲載しておりません。Tech Fun ITスクールのJava研修では、講師が丁寧に解説しています。

11.本章のまとめ

  • 例外を処理するときは「try・・catch文」で対応することが基本になる。
  • 例外の発生にかかわらず、必ず実行させたい処理は「finally」ブロック内に書く。
  • catch句は、処理する例外の種類や内容に応じて複数個書くことができるが、記述する順番に注意する必要がある。
  • 「throw文」を使用すると、意図的に例外を発生させることができる。
  • Exceptionクラスを継承すると、オリジナルの例外クラスを作成することができる。
  • メソッドが例外を発生する可能性がある場合は、「throws文」を使用してメソッド宣言に明示的に記述できる。

エラーを適切に扱うことはとても大事なことですので、スムーズに実装できるように何度も練習するとよいでしょう。

例外処理についての説明は、以上です。

執筆・編集

Tech Fun Magazine編集部
Tech Funの現役のITエンジニアが、システム開発の基礎知識や実践的なノウハウを執筆・編集しています。
Tech Fun ITスクールの研修講師として活躍するメンバーもおり、プログラミング初心者がつまづきやすいポイントを丁寧に解説しています。

ARTICLE
記事一覧

Java基礎

Java12からJava17までに導入された機能の紹介

システム開発の基本

プログラミングとテストの要点

データベース環境構築

データベース環境構築(Windows版) テストデータ作成

データベース環境構築

データベース環境構築(Windows版) MariaDBの設定

データベース環境構築

データベース環境構築(Mac版) テストデータ作成

データベース環境構築

データベース環境構築(Mac版) MariaDBの設定

Java基礎

はじめてのJava

Java基礎

Javaのデバッグ方法

Java基礎

ポリモフィズム

記事一覧を見る