パスワードを保存するための API を設計しているとしましょう。効果的な Java によると、スロー句を使用してチェック済み例外を表示することをお勧めしますが、チェック済み例外である SQLException をスローするスロー句を使用することで、API の基礎となる実装の詳細を明らかにしているため、後の段階で API の実装の詳細を変更できない。チェック例外をスローする利点の 1 つは、API を使用するプログラマーが、選択した方法で例外を処理できる必要があることです。これら2つの方法のどちらを選択する必要がありますか、実装を明らかにするスロー句を追加するか、それを非表示にするか、別のアプローチを使用しますか?
5 に答える
SQLException
クラスのユーザーに「漏れ」ないというあなたの動機は正しいです。
SQL を使用しているという事実は、実装の詳細と見なすことができます。後で SQL 永続性をメモリ内永続性に交換することもできますが、この変更はクラスのユーザーに影響を与えるべきではありません。
チェック済み例外を使用する傾向がある場合は、独自の例外タイプを定義します (たとえば、PasswordStoreException
名前の例)。これを使用して、スローされた元の例外をラップできます。たとえば、次のようになります。
try {
// do whatever
} catch (SQLException ex) {
throw new PasswordStoreException(ex);
}
- 現在、API がチェック済み例外を宣言することは、悪い設計と見なされています。このような API を使用したことがある場合は、その理由がすでにわかっているはずです。
- いずれにせよ、あなたの API は、他の API に属する例外をスロー (宣言は言うまでもなく) すべきではありません。それを行うと、クライアントの背中にまったく関係のない依存関係がぶら下がります。このルールの唯一の「例外」は、NPE、ISE などの JDK の標準例外です。
SQLException をキャッチし、独自の例外にラップします。
try {
// JDBC code
}
catch (SQLException e) {
throw new MyException("Error persisting the secret", e); // choose a better name, of course
}
この例外をチェック済み例外にするか実行時例外にするかは、呼び出し元がそれに対して何ができるかによって異なります。回復可能な場合 (ここではそうではないと思います)、それはチェック済み例外である必要があります。回復できない場合 (呼び出し元がエラー メッセージを表示するだけでよい場合)、実行時例外である必要があります。
それがチェック済みの例外である場合、選択の余地はありません。throws
メソッドの句で例外を宣言する必要があります。
そのままで、チェック済み/チェック解除済みの独自の例外をスローすることは常に良い考えです。ただし、その前に、可能であれば根本的な例外を修正してください。私はいつも以下の方法を好む、
try {
// JDBC code
}
catch (SQLException e) {
// try to solve the exception at API level
bollean solvable = trySolveException(e);
if (!solvable) {
// Alert the admin, or log the error statement for further debugging.
mailClient.sendMailToDBAdmin("Some issue storing password", e);
// or
LOG.severe("some issue in storing password " + e.toString);
throw MyException("A request/logstatement is logged on your behalf regarding the exception", e);
}
LOG.info("The exception is solved");
}
finally {
// don't forget to free your resources - to avoid garbage and memory leaks, incase you have solved the issue in trySolveException(e).
}
そう、
1) SRQException を直接公開するのではなく、独自のバージョンの例外をスローします。
2) 例外を一度解決しようとしましたが、そうでない場合は、メールまたはログ ステートメントを通じて何らかの方法で警告しました。
3) 最後に、例外の解決に成功した場合、すべてのリソースを解放したことになります。
新しい Java7 のtry with resource closeオプションを使用すると、finally 句を回避できます。
チェックされた例外とチェックされていない例外のどちらをスローするかについて、例を挙げます
1) NPE のような例外を言います - それらはプログラム上のエラーであり、開発者は NullPointer を作成しなかったことにもっと責任を持つべきです。コードがそのような不注意なエラーを考慮して、try(NPE)、catch(NPE) を配置するとは思わないでください。したがって、未チェックの例外をスローします。
2) 一方、SQL 例外のような例外はまれにあり、何らかの外部依存関係を説明します。したがって、ユーザー定義のチェック例外をスローする方がよいでしょう。また、ユーザーは、バックアップ SQL サーバーがあればそれに接続できるかどうかを判断できます。
3) プログラムがそれ以上続行できないという別の例外条項があります。範囲外の記憶を言ってください。それらはエラーとしてスローされる必要があります。
これを試して..
fillInStackTrace()
メソッドが呼び出され、新しく作成されたスロー可能オブジェクトのスタック トレース データが再初期化されます。API にアクセスしようとしたときに、例外に関する情報をマスクするのに役立ちます。