1. ホーム
  2. java

[解決済み] Javaにおけるチェック済み例外とチェックされていない例外の理解

2022-03-14 13:30:19

質問

ジョシュア・ブロッホ in " 効果的なJava "は次のように述べています。

チェックされた例外を使用する 回復可能な条件と実行時 プログラミングエラーに対する例外処理 (第2版では58項目)

この理解が正しいかどうか見てみましょう。

以下は、チェックされた例外についての私の理解です。

try{
    String userInput = //read in user input
    Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
    id = 0; //recover the situation by setting the id to 0
}

1. 上記はチェック済み例外とみなされますか?

2. RuntimeExceptionは未チェックの例外ですか?

以下、未チェックの例外について、私の理解を述べます。

try{
    File file = new File("my/file/path");
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){

//3. What should I do here?
    //Should I "throw new FileNotFoundException("File not found");"?
    //Should I log?
    //Or should I System.exit(0);?
}

4. さて、上記のコードもチェックされた例外にはならないのでしょうか?このように復旧を試みることができるのでしょうか?できるでしょうか? (注:3つ目の質問は catch 上記)

try{
    String filePath = //read in from user input file path
    File file = new File(filePath);
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){
    //Kindly prompt the user an error message
    //Somehow ask the user to re-enter the file path.
}

5. 人はなぜこんなことをするのか?

public void someMethod throws Exception{

}

なぜ例外を発生させるのか?エラーを早く処理したほうがいいのでは?なぜバブルアップするのか?

6. 正確な例外をバブルアップすべきか、Exceptionを使用してマスクすべきか?

以下は私の読み方です。

Javaでは、どのような場合にチェック例外を作成し、どのような場合に実行時例外を作成すればよいのでしょうか?

チェックされた例外とチェックされていない例外を選択する場合

どのように解決するのですか?

多くの人は、チェックされた例外(つまり、明示的にキャッチするか、再スローする必要がある例外)は、まったく使用すべきではないと言います。例えばC#では廃止されたし、ほとんどの言語にはない。だから、いつでも投げられるように RuntimeException (チェックされていない例外)

しかし、チェックされた例外は有用だと思います。例外的な状況をどう処理するか(回復可能かどうか)をAPIのユーザーに考えさせたいときに使われます。ただ、Javaプラットフォームではチェック付き例外が多用されすぎていて、それが嫌われる原因になっているんです。

以下は、このトピックに関する私の拡張見解です。 .

具体的な質問についてですが

  1. NumberFormatException はチェックされた例外と考えるか?
    いいえ。 NumberFormatException がチェックされていない(=のサブクラスである)。 RuntimeException ). なぜでしょうか?わからない。(しかし、メソッドがあったはずです isValidInteger(..) )

  2. RuntimeException は、チェックされていない例外ですか?
    はい、その通りです。

  3. ここでどうすればいいのでしょうか?
    それは、このコードがどこにあるか、そして何を起こしたいかによります。もしUIレイヤーにあるのなら、キャッチして警告を表示させ、サービスレイヤーにあるのなら、キャッチせずにそのままにしておきましょう。ただ、例外を飲み込まないようにしましょう。ほとんどのケースで例外が発生したら、これらのいずれかを選択する必要があります。

    • ログを記録して戻る
    • rethrow it (メソッドからスローされるように宣言する)
    • コンストラクタに現在の例外を渡して、新しい例外を構築します。
  4. さて、上記のコードもchecked exceptionにならないのでしょうか?こんな感じでリカバリーを試みてもいいのでしょうか?できるでしょうか?
    そうだったかもしれませんね。しかし、チェックされていない例外をキャッチすることも止めることはできません

  5. なぜ人々はクラスを追加するのでしょうか Exception をthrows節に入れることはできますか?
    多くの場合、人々は何をキャッチし、何を投げ直すかを検討するのが面倒だからです。投げる Exception は悪い習慣なので、避けるべきでしょう。

残念なことに、いつキャッチし、いつ再スローするか、いつチェックされた例外を使い、いつチェックされていない例外を使うかを決定できる単一のルールは存在しません。このことが多くの混乱と多くの悪いコードの原因になっていることに私は同意します。一般的な原則はBlochによって述べられている(あなたはその一部を引用した)。そして、一般的な原則は、例外を処理できるレイヤーに例外を再スローすることです。