まずは問題を見ろ
→ javadrill.tech で出題された問題を見る(Step06)
問題のポイント
throws
を書くことで、「このメソッドは例外を投げる可能性があるぞ」と宣言できる。try-catch
を自分で書くのではなく、呼び出し元に処理を委ねるスタイルを理解しろ。- 例外の設計とは、「誰が責任を持つか」を設計することでもある。
まず、日本語で考えろ
ある処理が、例外を起こす可能性があるとする。
けどその場で try-catch
して処理を止めるのが正しいとは限らない。
ときには「オレじゃなくて上で処理してくれ」って投げ返す設計が必要になる。
それが throws
という書き方や。
コメントを書け
// 例外を自ら発生させるメソッド riskyMethod を定義
// このメソッドでは try-catch を使わず、throws で呼び出し元に任せる
// 呼び出し元で try-catch して例外を処理する
コメントに従ってコードを書け
public class ExceptionUtil {
public static void riskyMethod() throws Exception {
throw new Exception("危険な処理です");
}
}
public class Main {
public static void main(String[] args) {
try {
ExceptionUtil.riskyMethod();
} catch (Exception e) {
System.out.println("エラーを受け取りました: " + e.getMessage());
}
}
}
実行結果の例
エラーを受け取りました: 危険な処理です
コードの解説
throws
をつけると、「このメソッドは例外を投げる可能性がある」と明示できるthrow new Exception(...)
で例外を実際に発生させている- ただし、このメソッドを呼ぶ側が
try-catch
を用意してないとコンパイルエラーになる(←ここ重要) - この構造により、責任の所在が明確になる
→ どこで握って、どこで流すか。それが設計や。
つまづきやすいポイント
throws
とthrow
はまったくの別物throw
→ 例外を発生させるthrows
→ メソッドが例外を投げる可能性を宣言する
Exception
を throws に書いた場合、呼び出し元でcatchしないと強制的にエラーになるRuntimeException
はthrowsなしでも書けるが、それは別の話(後述)
// tesh:
// オレらが書くコードには、「責任」がある。
// 「ここで止めるか」「流すか」は、その責任をどう扱うかの話や。
//
// 全部自分で処理するな。他人に任せていい場面もある。
// そのために、throws はある。
//
// Just keep typing, baby.
// 書くってことは、投げることでもある。流し先まで設計に入れろ。