10

Java で例外を再スローすることについて、非常に簡単な質問があります。

コード スニペットは次のとおりです。

public static void main(String[] args) throws FileNotFoundException {
    try {
        FileReader reader = new FileReader("java.pdf");
    } catch (FileNotFoundException ex) {
        throw ex;
    }
}

public static void main(String[] args) throws FileNotFoundException {        
        FileReader reader = new FileReader("java.pdf");        
}

2 番目のバージョンはよりエレガントに見えるのに、なぜex最初のバージョンを再投入する必要があるのでしょうか? どのような利点があり、どのバージョンが他のバージョンよりも優先されますか?

4

7 に答える 7

15

あなたが正しいです。2番目のバージョンの方が優れています。さらに、最初のバージョンは意味がありません。例外のスタックトレースが「間違っている」ことを除いて、同じことを行います。

例外を「再スロー」する理由は次のとおりです。

  1. その前にやることがあるなら。
  2. あるタイプの例外をキャッチして、他のタイプの例外をスローする場合:

例:

try {
   // do something
} catch (IOException ioe) {
    throw new IllegalStateException(ioe);
}
于 2012-08-15T16:01:25.543 に答える
9

与えられた例では、再スローはException目的を果たしません。

これを行うと、例外をキャッチしてから再スローするメソッドが、を確認したときに追加のアクションを実行する必要があり、呼び出し元がを確認してアクションを実行できるように、が呼び出し元に伝播されることをException望んでいる場合に役立ちます。 。ExceptionException

于 2012-08-15T15:59:58.710 に答える
8

例外を(単にスローするのではなく)キャッチ/再スローするのは、catchブロックで何か他のことをしたい場合だけです。たとえば、再スローする前にロギングステートメントを記述します。

于 2012-08-15T15:59:38.497 に答える
3

問題は、例外を再スローする必要があると考える理由です。Eclipse は で囲むことを提案しましたtry-catchか? 実際には、同じ例外を再スローすることはめったにありませんが、特にラッパー例外がチェックされていない場合は、1 つをキャッチして、最初の例外をラップする別の例外をスローすることがよくあります。これは、チェックされた例外を宣言する呼び出しがある場合に発生しますが、それらの呼び出しを記述するメソッドはそれらの例外を宣言しません。

public int findId(String name) {
  try {
    return db.select("select id from person where name=?", name);
  } catch (SQLException e) {
    throw new RuntimeException(e);
  }
}
于 2012-08-15T16:08:54.003 に答える
3

終了する前に例外で何かをしたいことに加えて-ログ記録のように、別の例外としてそれをラップしたい場合は、次のようにします:

try {
    FileReader reader = new FileReader("java.pdf");
} catch (FileNotFoundException ex) {
    throw new ServletException(ex);
}
于 2012-08-15T16:04:11.910 に答える
2

どちらのバージョンも同じスタックトレースを出力します

トライ/キャッチなし

import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
//        try {
            FileReader reader = new FileReader("java.pdf");
//        } catch (FileNotFoundException ex) {
//            throw ex;
//        }
    }
}

出力します

Exception in thread "main" java.io.FileNotFoundException: java.pdf (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at Test.main(Test.java:7)

try/catch/throw と同じ例外を使用

import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test {
    public static void main(String[] args) throws FileNotFoundException {
        try {
            FileReader reader = new FileReader("java.pdf");
        } catch (FileNotFoundException ex) {
            throw ex;
        }
    }
}

以前とまったく同じように出力されます

Exception in thread "main" java.io.FileNotFoundException: java.pdf (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at Test.main(Test.java:7)

try/catch/throw ラッピング例外

推奨されるアプローチは、独自の例外をスローすることです。根本原因の詳細を提供する場合は、キャッチした例外をラップします (必要な場合とそうでない場合があります)。

import java.io.FileNotFoundException;
import java.io.FileReader;

public class Test {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("java.pdf");
        } catch (FileNotFoundException ex) {
            throw new RuntimeException("Error while doing my process", ex);
        }
    }
}

最上位の問題 (私のプロセスが完了していない) と、その原因となった根本原因 (java.pdf ファイルが見つかりません) を明確に確認できます。

Exception in thread "main" java.lang.RuntimeException: Error while doing my process
    at Test.main(Test.java:9)
Caused by: java.io.FileNotFoundException: java.pdf (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at java.io.FileReader.<init>(FileReader.java:58)
    at Test.main(Test.java:7)
于 2017-03-30T09:35:16.747 に答える
2

throw実行の流れはステートメントの直後に停止します。後続のステートメントは実行されません。最も近い外側のブロックが検査され、例外のタイプに一致tryするステートメントがあるかどうかが確認されます。catch

一致が見つかった場合、制御はそのステートメントに移されます。そうでない場合は、次の囲みtryステートメントが検査されます。一致するcatchものが見つからない場合、デフォルトの例外ハンドラはプログラムを停止し、スタック トレースを出力します。

メソッドが処理しない例外を引き起こす可能性がある場合、メソッドの呼び出し元がその例外から身を守ることができるように、この動作を指定する必要があります。

throwsメソッドの宣言に句を含めることで、これを行うことができます。throws句には、メソッドがスローする可能性のある例外の種類がリストされています。Errorこれは、またはタイプの例外、RuntimeExceptionまたはそのサブクラスを除くすべての例外に必要です。throwsメソッドがスローできる他のすべての例外は、句内で宣言する必要があります。そうでない場合、コンパイル時エラーが発生します。

于 2017-01-05T17:23:55.977 に答える