web-dev-qa-db-ja.com

Javaメソッド宣言でスローを使用する場合

だから、Javaでの例外処理についての基本的な理解は十分にあると思っていましたが、最近、混乱と疑念を生じさせるコードを読んでいました。ここで対処したい主な疑問は、次のようなJavaメソッド宣言で人がいつスローを使用すべきかということです。

    public void method() throws SomeException
    {
         // method body here
    }

似たような投稿を読んで、私はそれを集めます 投げる メソッドの実行中にSomeExceptionがスローされる可能性があるという宣言の一種として使用されます。

私の混乱は、次のようなコードに由来しています。

     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

使用したい理由はありますか 投げる この例では? IOExceptionのようなものの基本的な例外処理をしているだけなら、try/catchブロックが必要なだけだと思われます。

81
jbranchaud

例外タイプをキャッチする場合、再スローする場合を除き、例外をスローする必要はありません。投稿する例では、開発者は両方ではなく、どちらか一方を実行する必要があります。

通常、例外を使用して何も実行しない場合は、キャッチするべきではありません。

あなたができる最も危険なことは、例外をキャッチし、それで何もしないことです。

例外をスローするのが適切な場合の良い議論はこちらです

例外をスローするタイミング?

78
hvgotcodes

メソッドがチェック済み例外をスローする場合にのみ、メソッドにthrows句を含める必要があります。メソッドが実行時例外をスローする場合、そうする必要はありません。

チェック済み例外と未チェック例外の背景については、こちらを参照してください。 http://download.Oracle.com/javase/tutorial/essential/exceptions/runtime.html

メソッドが例外をキャッチして内部で処理する場合(2番目の例のように)、throws句を含める必要はありません。

21
Shane Bell

あなたが見たコードは理想的ではありません。次のいずれかを行う必要があります。

  1. 例外をキャッチして処理します。その場合、throwsは不要です。

  2. try/catchを削除します。この場合、例外は呼び出しメソッドによって処理されます。

  3. 例外をキャッチし、場合によっては何らかのアクションを実行してから、例外を再スローします(メッセージだけでなく)

9
Damo

その例では、throwsは不要です。以前の実装から残っている可能性があります-おそらく、キャッチブロックでキャッチされる代わりに、例外が最初にスローされた可能性があります。

2
RevBingo

これは答えではなく、コメントですが、フォーマットされたコードでコメントを書くことができなかったので、ここにコメントがあります。

と言うことができます

public static void main(String[] args) {
  try {
    // do nothing or throw a RuntimeException
    throw new RuntimeException("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

出力は

test
Exception in thread "main" Java.lang.RuntimeException: test
    at MyClass.main(MyClass.Java:10)

このメソッドは「スロー」例外を宣言しませんが、スローします!トリックは、スローされた例外がメソッドで宣言する必要のないRuntimeExceptions(未チェック)であることです。彼女が見るのは「スローe」だけなので、このメソッドの読者には少し誤解を招くかもしれません。ステートメントがスロー例外の宣言なし

今、私たちが持っている場合

public static void main(String[] args) throws Exception {
  try {
    throw new Exception("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

メソッドで「スロー」例外を宣言する必要があります。そうしないと、コンパイラエラーが発生します。

1
Αλέκος

投稿したコードは間違っています。IOExceptionを処理するために特定の例外をキャッチしているが、キャッチされていない例外をスローする場合、例外をスローする必要があります。

何かのようなもの:

public void method() throws Exception{
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println(e.getMessage());
   }
}

または

public void method(){
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println("Catching IOException");
           System.out.println(e.getMessage());
   }catch(Exception e){
           System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc.");
           System.out.println(e.getMessage());
   }

}

1

指定した例では、メソッドはIOExceptionをスローしないため、宣言は間違っています(ただし有効です)。私の推測では、元のメソッドはIOExceptionをスローしましたが、その後、例外を処理するように更新されましたが、宣言は変更されていません。

1
DaveJohnston