web-dev-qa-db-ja.com

Java例外をスローするときのベストプラクティス:コアをスローするJava例外

new Exception("Some message", maybeSomeCause)をスローする代わりに、メソッドのすべての呼び出し元がException(RuntimeExceptionsを含めることができる)をキャッチする必要があることを意味します。問題が発生したときに、より具体的なタイプの例外をスローしたいと思います。

Exceptionまたは別の例外タイプを拡張する独自の例外タイプを作成できますが、コアJava言語に付属するいくつかの例外を再利用することをお勧めします。

  • IllegalArgumentException
  • UnsupportedOperationException
  • IOException
  • その他?

私が行方不明になっている他のものはありますか?ここで「コア」例外の基本的なリストを見つけました: http://rymden.nu/exceptions.html 、ユーモラスな説明付き。

ありがとう!

編集:

「コア」例外の良いリストはありますか?

これまでのリスト:

28
Jon Onstott

はい、それはとても良いことです。実際、それはEffective Java、2nd ed。 248ページの項目60を参照してください:「標準例外の使用を支持する」

既存の例外を再利用することには、いくつかの利点があります。これらの中で最も重要なのは、プログラマーがすでに慣れ親しんでいる確立された規則に一致するため、APIの学習と使用が容易になることです。 2つ目は、APIを使用するプログラムは、見慣れない例外が散らかっていないため、読みやすいということです。最後に(そして少なくとも)、例外クラスが少ないということは、メモリフットプリントが小さく、クラスのロードに費やされる時間が少ないことを意味します。

24

あなたの質問で提供されたリストは、クイックリファレンス資料としてあまり使用できず、開発ドキュメントのほとんどの説明は私にはわかりにくいようです。

最も再利用可能な組み込み例外の短いリストに出くわしたことはありません。以下のものを作成するために最善を尽くしましたが、完璧にはほど遠いと確信しています。

github Gist link (または以下の現在のコンテンツを参照)

再利用可能な組み込み例外のリスト

推定ユーティリティ別に整理

IllegalArgumentException

メソッドに違法または不適切な引数が渡されたことを示すためにスローされます。

IndexOutOfBoundsException

ある種のインデックス(配列、文字列、ベクトルなど)が範囲外であることを示すためにスローされます。

ArithmeticException

要求された数学演算が無意味または不可能な場合にスローされます。例:_int x = 1/0_;

IllegalStateException

アプリケーションは、要求された操作に対して適切な状態ではありません。例:ファイルがロードまたは作成される前に保存しようとしています。

DataFormatException

不適切にフォーマットされたデータを受信した場合は、これをスローします。例:MyClass.applyJSONString("{non:sense,all,garbled=definitely.not;json{{{")

TimeoutException

何かに時間がかかりすぎて諦めている場合は、これを投げてください。

KeySelectorException

キーを使用してオブジェクトを検索しようとしていて、オブジェクトが見つからなかった場合、またはキーが無効である場合は、これをスローするのが理にかなっていると思いますが、 dev docs onを本当に理解していません。それ。

例:_lookup_key_がデータ構造にない場合のmyDataStructure.get("lookup_key");

IOException

読み取り/書き込みに問題がありますか?この例外をスローします。

ScriptException

何らかの形式のスクリプトを実行していて、問題が見つかった(I/Oや解析ではない)?この例外をスローします。

GeneralSecurityException

セキュリティ関連の問題が発生した場合は、これをスローしてください。

RuntimeException

これは、他のカテゴリにうまく当てはまらないランタイムエラーに使用します。

17
7yl4r

コアライブラリの既存の機能を複製しない限り、ほとんどのコア例外は特殊すぎて直接使用できません。たとえば、おそらくUnknownHostExceptionのインスタンスを作成する必要はありません。ホストの解決に失敗した場合、呼び出したInetAddressまたはSocketFactoryメソッドはすでに作成されており、例外がスローされています。

私が一般的に使用できることがわかった唯一の例外は、IOExceptionIllegalArgumentExceptionIllegalStateException、およびUnsupportedOperationExceptionです。

IOException-インターフェース、ネットワーク、およびハードドライブアクセスに関するすべての問題はこれに該当します。外部データまたはハードウェアにアクセスするためのコードを作成している場合は、これを使用する必要があります。たとえば、特定の種類のネットワークデバイスにアクセスするためのAPIを実装している場合、デバイスがエラーステータスを返したり、何か奇妙なことをしたときに、MyDeviceExceptionサブクラスをスローすることができます。また、1つ以上の低レベルのライブラリ呼び出しからIOExceptionをキャッチし、接続チェックのスローなど、高レベルのメッセージで別のIOExceptionにラップしたい場合もあります。 「リクエストがタイムアウトしました」例外によって引き起こされた「デバイスが利用できません」例外。

IllegalArgumentException-パラメータチェックはこれをスローする必要があります。たとえば、サイズパラメータの負の整数、または予期しないnull。これはチェックされていない例外ですが、メソッドの前提条件をより明確にするために、とにかく文書化することをお勧めします。コアライブラリには多くの例があります。

IllegalStateException-メソッドパラメータが有効であるが、メソッドに必要な一部の内部データまたは機能が利用できず、より適切なチェック済み例外がない場合(IOExceptionなど)にこれを使用できます。 。これが必要ないように物事を設計する方が良い場合がよくあります。

UnsupportedOperationException-何かのサブクラスを作成し、スーパークラスメソッドの1つが概念的に無効である場合は、それをオーバーライドして、これらの1つをスローします。 Javaのコレクションインターフェイスは不変性をサポートするように設計されていないため、Guavaはこれを 不変のコレクションクラス に使用します。これは、スーパークラスの設計が悪いことを示している傾向があります。何もしないか、null/emptyを返すことが適切で驚くべき結果ではない場合は、使用しないでください。

2
Sean Van Gorder

例外がスローされる原因となったシナリオを合理的に説明している場合は、Exceptionクラスを再利用することは絶対に理にかなっています。

1
darrengorman

コードのユーザーが2つの異なる例外に対して異なることを行う必要がある場合、それらは別個の例外タイプである必要があります。とは言うものの、JDK例外は、「プログラマーエラー」例外のほとんどをカバーします。たとえば、IllegalArgumentExceptionがスローされた場合、これはプログラミングの間違いを示しており、実行時に処理する必要があるものではありません。

0
Louis Wasserman