スタックトレースを失わずにJavaで例外を再スローする


417

C#では、throw;ステートメントを使用して、スタックトレースを保持しながら例外を再スローできます。

try
{
   ...
}
catch (Exception e)
{
   if (e is FooException)
     throw;
}

このようなJavaの何か(元のスタックトレースを失わない)はありますか?


4
なぜ元のスタックトレースが失われると思いますか?新しいSomeOtherExceptionをスローし、コンストラクターまたはinitCause()で根本原因を割り当てるのを忘れたときにそれを失う唯一の方法。
akarnokd 2009

4
これは.Netでコードがどのように動作するかと思いますが、私はもう前向きではありません。どこかで調べるか、小さなテストを実行することは価値があるかもしれません。
ripper234 2009

11
Throwableそれらをスローすることによって変更されることはありません。スタックトレースを更新するには、を呼び出す必要がありますfillInStackTrace()。便利なことに、このメソッドはのコンストラクタで呼び出されThrowableます。
ロバート

50
C#では、はい、throw e;スタックトレースが失われます。しかしJavaではありません。
Tim Goodman

回答:


560
catch (WhateverException e) {
    throw e;
}

キャッチした例外を単に再スローします(明らかに、周囲のメソッドは、シグネチャなどを介してこれを許可する必要があります)。例外は、元のスタックトレースを維持します。


4
こんにちは、InterruptedException eは、throw e行を追加すると、未処理の例外メッセージを表示します。それをより広い例外eに置き換えるとそうではありません。これはどのように正しく行われるべきですか?
ジェームズP.

1
@ジェームズ、関数宣言に「スローXxxException」を追加するとメッセージが消えることを確認しました。
shiouming

2
Java 7では、このような再スローのためのコンパイラーはよりインテリジェントです。現在は、containingメソッドの特定の「スロー」例外で正常に動作します。
WaldemarWosiński2013年

193
@ジェームズ場合はcatch(Exception e) { throw e; }処理されません。catch(InterruptedException ie) { throw ie; }取り扱った場合。経験則として、catch(Exception e)これはポケモンではありません。私たちはすべてをキャッチしたくありません。
corsiKa 2013年

3
@corsiKa "Catch 'em all"を実行したくないというのは必ずしも本当ではありません。それは単なる別のユースケースです。トップレベルのループまたはイベントハンドラー(たとえば、スレッドの実行内)がある場合、少なくともRuntimeExceptionをキャッチしてログに記録しないと、例外を完全に見逃してしまい、何のために重要なループを静かに抜けてしまうことがよくあります。多くの場合、1回限りの障害です。これは、追加のコードが何を行うか、何をスローするかわからないプラグイン機能にも非常に適しています...これらのキャッチダウンのようなトップダウンの用途では、例外は多くの場合、優れたアイデアであるだけでなく、ベストプラクティスです。
ビルK

82

を好む:

try
{
    ...
}
catch (FooException fe){
   throw fe;
}
catch (Exception e)
{
    // Note: don't catch all exceptions like this unless you know what you
    // are doing.
    ...
}

6
ジェネリックよりも特定の例外をキャッチし、そのインスタンスをチェックするために、Javaでは間違いなく適切です。+1
amischiefr 2009

8
-1何をしているのかわからない場合は、単純な「例外」をキャッチしてはならないため。
ストロボスコップ2009

19
@Stroboskop:真ですが、回答するには、質問と同じ(類似した)コードを使用するのが最善です!
user85421 2009

14
ときどきすべての例外をキャッチしても問題ありません。テストケースを書いているときなど。または、ロギングの目的で。または、メインでキャッチしないとクラッシュします。
John Henckel 2014年

1
@JohnHenckelなど:有効なポイントが含まれています。質問を更新Exceptionして、ほとんどの(すべてではない)場合に、キャッチすることは通常適切なことではないことを明確にしました。
Lundberg氏による

74

例外を別の例外にラップし、例外を原因パラメーターとしてThrowableとして渡すことにより、元のスタックトレースを保持することもできます。

try
{
   ...
}
catch (Exception e)
{
     throw new YourOwnException(e);
}

8
一緒にメッセージを追加することもお勧めしますthrow new YourOwnException("Error while trying to ....", e);
Julien

これは私が探していたもの、特に最初のコメントからのバージョンで、独自のメッセージを渡すことができます
Csaba

これはエラーメッセージを正しく表示しますが、スタックトレースはエラー行を「throw new .......(e)」の行として示し、例外を引き起こした元の行ではありません。
アッシュバーンRK

22

Javaでもほぼ同じです。

try
{
   ...
}
catch (Exception e)
{
   if (e instanceof FooException)
     throw e;
}

5
いいえ、新しいExceptionオブジェクトをインスタンス化しない限り、スタックトレースは同じままです。
Mnementh 2009

28
私はFooExceptionの特定のキャッチを追加します
dfa 2009

3
この特定のケースでは同意しますが、特定のキャッチを追加することは正しい選択ではない可能性があります-すべての例外に共通のコードがあり、特定の例外の後でそれを再スローするとします。
エルブ2009

1
@MarkusLausbergしかし、最終的に例外をキャッチしません。
ロバート

はい、しかしこれは問題ではありませんでした。
Markus Lausberg、2012

14

Java throw eでは、単にではなく、キャッチした例外をスローするだけthrowです。Javaはスタックトレースを維持します。


6

このようなもの

try 
{
  ...
}
catch (FooException e) 
{
  throw e;
}
catch (Exception e)
{
  ...
}

5
public int read(byte[] a) throws IOException {
    try {
        return in.read(a);
    } catch (final Throwable t) {
        /* can do something here, like  in=null;  */
        throw t;
    }
}

これは、メソッドがをスローする具体的な例IOExceptionです。このfinal手段tは、tryブロックからスローされた例外のみを保持できます。追加の読み物はここここにあります



3

スタックトレースは、キャッチされた例外を他の例外にラップして(詳細を提供するため)、またはキャッチされた例外を単に再スローした場合に保持されます。

try{ ... }catch (FooException e){ throw new BarException("Some usefull info", e); }


2

私はちょうど同じような状況で、コードが、再スローしたいいくつかの異なる例外をスローする可能性があります。上記の解決策は私にとってthrow e;はうまくいきませんでした。Eclipseから、処理されない例外につながると言われたので、私はこれを実行しました:

try
{
...
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {                    
    throw new RuntimeException(e.getClass().getName() + ": " + e.getMessage() + "\n" + e.getStackTrace().toString());
}

私のために働いた.... :)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.