例外の原則で有名な"Throw early, catch late"の紹介です。1
ざっくり説明
Throw early(早く投げろ)
- 例外的な状況になったらさっさと例外をThrowしよう
Catch late(後でキャッチしろ)
- 例外をハンドリングするのは、例外をどうハンドリングすべきかを知っている場所でやろう
- どうハンドリングすべきかを知らない場所では余計なことをしちゃダメ
具体例を交えて説明
なぜThrow earlyなのか
例外的な状況に遭遇したら処理を続行できるわけがないため。(至極当然な話をしています)
Throw earlyをちゃんとやっている例
public class FileUtil {
/** 指定されたパスのファイルを全部読み込んで文字列で返す。*/
public static String readAll(String path) {
if (path == null) {
throw new NullPointerException("パスが指定されてないからファイルを読み込めるわけがないよ。。。");
}
if (!Files.exists(path)) {
throw new FileNotFoundException("指定されたファイルが存在しないからファイルを読み込めるわけがないよ。。。");
}
// 以下略
}
}
なぜCatch lateなのか
基本的に例外をどうハンドリングすべきかを知っているのは呼び出し元(上位層)であるため。
例
前出のFileUtil#readAll(path)
にとっては、指定されたファイルが存在しないという状況は処理が続行できない状況(つまり例外的な状況)でした。
しかしながらFileUtil#readAll(path)
を呼び出している上位層にとっては、ファイルが存在しないのは想定済みの状況(つまり処理が続行できる状況)かもしれません。↓
public class BusinessLogic {
/**
* `hoge.txt`の中身を標準出力する。
* `hoge.txt`が存在しなければ`Not exist.`と標準出力する。
*/
public static void execute() {
try {
String text = FileUtil.readAll("hoge.txt");
System.out.println(text);
} catch (FileNotFoundException e) { // ファイルが存在しなかった場合
System.out.println("Not exist.");
}
}
}
このような状況でもしFileUtil#readAll(path)
で余計なハンドリングをしてしまった場合、色々と問題が起きてしまいます。
余計なハンドリングの例
例外をThrowせずにプロセスを停止する
public static String readAll(String path) {
// 中略
if (!Files.exists(path)) {
System.exit(1);
}
// 後略
}
プロセスを停止してしまったら業務が遂行できません。(本当はNot exist.
と標準出力するのが正解なのに。。。)
エラーログを出力してから例外をThrow
public static String readAll(String path) {
// 中略
if (!Files.exists(path)) {
LOGGER.error("指定されたファイルが存在しません!");
throw new FileNotFoundException("指定されたファイルが存在しないからファイルを読み込めるわけがないよ。。。");
}
// 後略
}
もしシステムが「エラーログを検知したら即座にエンジニアに連絡!」みたいな仕組みになっていた場合、業務的には問題ないハズなのにエンジニアに連絡が来るようになってしまいます。
まとめ
- 例外的な状況になったらさっさと例外をThrowする。
- 例外をどうハンドリングすればわからないときは上位層に任せる。 余計なことはしない。
おすすめ記事
-
Exceptions: Why throw early? Why catch late?
Throw early, catch late
でググると一番上に出てくるやつ。 読もう。 - 早期リターンを書こう 早期リターンを心がけていれば自然とThrow earlyになる……ハズ。
-
Java 例外処理における 11 個の誤り 例外処理で気にすることは
Throw early, catch late
だけじゃないので注意。
記事を書いてみた感想
プライベートな時間を使ってコンスタントにアウトプットし続けられる人って本当にすごい。 えらすぎる。
-
有名だと思ってたけど意外と日本語の記事がなかったので書いてみた。 ↩