ジョシュア・ブロックは「Effective 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. 正確な例外をバブルアップする必要がありますか、それとも例外を使用してマスクする必要がありますか?
以下は私の読み物です
ベストアンサー1
多くの人が、チェック済み例外 (つまり、明示的にキャッチまたは再スローする必要がある例外) はまったく使用すべきではないと言います。たとえば、チェック済み例外は C# では削除されており、ほとんどの言語には存在しません。したがって、常にRuntimeException
(チェックされていない例外) のサブクラスをスローできます。
しかし、チェック例外は便利だと思います。チェック例外は、例外的な状況 (回復可能な場合) の処理方法を API のユーザーに考えさせたい場合に使用します。チェック例外は Java プラットフォームで過度に使用されているため、嫌われています。
具体的な質問については、
NumberFormatException
はチェック例外とみなされますか
?いいえ。NumberFormatException
はチェックされていません (= のサブクラスですRuntimeException
)。 なぜでしょうか? わかりません。 (ただし、メソッド があるはずですisValidInteger(..)
)RuntimeException
チェックされない例外ですか
?はい、その通りです。ここで何をすべきでしょうか?
このコードがどこにあり、何が起きてほしいかによって異なります。UI レイヤーにある場合はキャッチして警告を表示します。サービス レイヤーにある場合はキャッチせずにそのままにしておきます。例外を飲み込まないでください。例外が発生した場合、ほとんどの場合、次のいずれかを選択する必要があります。
- ログに記録して返す
- それを再度スローする(メソッドによってスローされるように宣言する)
- 現在の例外をコンストラクタに渡して新しい例外を構築する
さて、上記のコードもチェック例外になるのではないでしょうか。このようにして状況を回復することはできますか? できますか?
そうできたかもしれません。しかし、チェックされていない例外をキャッチすることを妨げるものは何もありません。なぜ
Exception
throws 節にクラスを追加するのでしょうか?
ほとんどの場合、何をキャッチし、何を再スローするかを考えるのが面倒だからです。スローはException
悪い習慣であり、避けるべきです。
残念ながら、いつキャッチし、いつ再スローし、いつチェック済み例外を使用し、いつ未チェック例外を使用するかを決定する単一のルールはありません。これが多くの混乱と多くの不適切なコードの原因になっていることに同意します。一般原則は Bloch によって述べられています (その一部を引用しました)。そして、一般原則は、例外を処理できるレイヤーに例外を再スローすることです。