web-dev-qa-db-ja.com

コードでランタイム例外を処理することは良い習慣ではありませんか?

Java=アプリケーションで作業しており、ランタイム例外が多くの場所で処理されていることがわかります。たとえば、

try {
    // do something
} catch(NullPointerException e) {
    return null;
}

私の質問は、いつランタイム例外を処理するのが良い習慣なのですか?例外はいつ処理しないでおくべきですか?

11

場合によります。

例えば、 Integer#parseIntは、提供された文字列を解析できない場合、NumberFormatException(RTE)をスローします。しかし、ユーザーが整数用のテキストフィールドに「x」を書き込んだという理由だけで、アプリをクラッシュさせたくないのは確かです。そして、最初に文字列を解析しようとしない限り、文字列を解析できるかどうかはどうやってわかりますか?したがって、この場合、RTEは単なるエラー信号であり、何らかのエラーメッセージを表示するはずです。 すべきはチェックされた例外であると主張することができますが、あなたができること-それはそうではありません。

18
Joonas Pulakka

NullPointerExceptionsは通常、nullチェックがないことを示しています。したがって、このようにキャッチする代わりに、適切なnullチェックを追加して、例外をスローしないようにする必要があります。

しかし、RunTimeExceptionsを処理するのが適切な場合もあります。たとえば、適切な場所にnullチェックを追加するようにコードを変更できない場合、または例外がNullPointerException以外の場合です。

例外処理の例はひどいです。これを行うと、スタックトレースと問題に関する正確な情報が失われます。そして、おそらく別の場所で別のNullPointerExceptionをトリガーし、何が起こったのか、およびそれを解決する方法について誤解を招く情報を取得するため、実際にはそれを解決していません。

7
deadalnix

私は、期待する例外を処理します。 (DBの読み取り/書き込みエラーと同様)。予期しない例外が発生します。他のどこかが例外を予期していて、そのためのロジックを持っている可能性があります。

4
SoylentGray

例外はそれだけであるべきです。例外を使用する場合のベストプラクティスは、例外を使用して、予期しないことが発生すると思われる状況をカバーすることです。古典的な例は、ファイルが存在しない場合にスローされるFileNotFoundExceptionです。ファイルの存在をテストする場合は、何かにぶつかったかどうかを確認するために10フィートのスティックで突き出すだけなので、File.exists()を使用します。

トライキャッチでファイルを囲み、ファイルが存在するかのように使用することで、技術的に同じ結果を得ることができますが、A)例外は一般にリソースの点でコストがかかり、B)プログラマは、ファイルが存在することを意味すると想定しますプログラムの全体的な混乱を増すトライキャッチ。

データベースから値をフェッチするメソッドを作成する状況はたくさんあります。 1000の問題が発生する可能性があり、小さな情報が1つだけ必要であることを考えると、5つのさまざまな例外を含むトライキャッチリストで通話を囲むのは不便です。そこで、fetchメソッドで例外をキャッチします。何か問題が発生した場合は、データベース接続を閉じるために適切なアクションを実行するか、finally句の何も実行せずにnullを返します。これは、コードを単純化するだけでなく、「null」が例外から取得した可能性があるのと同じメッセージを送信するため、良い習慣です。 fetchメソッドで例外の詳細を管理しますが、結果がnullであるかどうかを確認して、受信側で予定どおりに機能しない場合の処理​​を管理します。

例えば:

Integer getUserCount() {
   Integer result = null;
   try {
      // Attempt to open database and retrieve data
   } catch (TimeoutException e) {
      logger.error("Got a watch?");
   } catch (MissingDatabaseException e) {
      logger.error("What are you smoking?");
   } catch (PermissionsToReadException e) {
      logger.error("Did you *really* think you were getting away with that?");
   } catch (PressedSendButtonToHardException e) {
      logger.error("Seriously.. just back away from the computer... slowly..");
   } catch (WTFException e) {
      logger.error("You're on your own with this one.. I don't even know what happened..");
   } finally {
      // Close connections and whatnot
   }
   return result;
}

void doStuff() {
   Integer result = getUserCount();
   if(result != null) {
       // Went as planned..
   }
}
2
Neil