なぜできますか"偽"のスタックトレースの例外のJava?
質問
また、下記の試験に失敗した:
public class CrazyExceptions {
private Exception exception;
@Before
public void setUp(){
exception = new Exception();
}
@Test
public void stackTraceMentionsTheLocationWhereTheExceptionWasThrown(){
String thisMethod = new Exception().getStackTrace()[0].getMethodName();
try {
throw exception;
}
catch(Exception e) {
assertEquals(thisMethod, e.getStackTrace()[0].getMethodName());
}
}
}
以下のエラー:
Expected :stackTraceMentionsTheLocationWhereTheExceptionWasThrown
Actual :setUp
のスタックトレースするだけで平行います。
なぜできないのではないでスタックトレースに書き直した時に例外がスローされます?私はJava devとになったかもしれない何かが足りない。
解決
スタックトレースは、それがスローされたときに例外はなく、インスタンス化されるときに作成されます。 Java言語仕様のrel="noreferrer">の
私はの理由の彼らはそのようにしましたが、仕様はそのように定義している場合、それはすべてのさまざまなJava VM上で、少なくとも一貫してます。 ただし、手動で また、あなたの代わりに20.22.1 public Throwable()
This constructor initializes a newly created Throwable object with null as
its error message string. Also, the method fillInStackTrace (§20.22.5) is
called for this object.
....
20.22.5 public Throwable fillInStackTrace()
This method records within this Throwable object information about the
current state of the stack frames for the current thread.
exception.fillInStackTrace()
を呼び出すことによって、それを更新することができます。Thread.currentThread().getStackTrace()
(悪いスタイル)を使用してのnew Exception().getStackTrace()
を使用する必要があることに注意します。
他のヒント
例外のスタックトレースは、例外の作成時に入力されます。それ以外の場合は、を例外をキャッチし、それを処理し、それはの再スローすることは不可能であろう。オリジナルのスタックトレースは、迷子になります。
あなたはこれを強制したい場合は、あなたは明示的にexception.fillInStackTrace()
を呼び出す必要があります。
あなたがそのスタックトレースを書き換えることを要求していないので。これは、セットアップの方法でそれを作成したときに設定され、あなたはそれを変えるために何かをしたことはなかったです。
Exceptionクラスを使用すると、メソッド名を設定するためのあらゆる機会を与えるものではありません。それは不変です。だから私は、あなたが可能性がどこに反射のような凶悪なものに頼るしたい場合を除き、メソッド名を再設定するの知っている方法はありません。
あなたはJUnitのか、TestNGのを使用している場合、私は、静的インポートを見ることはできませんのでご@Testアノテーションには、私に教えてくれませんが、いずれの場合も、あなたは、特定の例外を使用することによってスローされたかどうかを確認するテストを実行することができます@Test注釈で「期待される」メンバーます。
あなたは、スタックのトラックを変更する例外をスローたくないだろうか、あなたが安全に、例外を再スローしない可能性があります。
public void throwsException() {
throw new RuntimeException();
}
public void logsException() {
try {
throwsException();
} catch (RuntimeException e) {
e.printStrackTrace();
throw e; // doesn't alter the exception.
}
}
@Test
public void youCanSeeTheCauseOfAnException(){
try {
logsException();
} catch(Exception e) {
e.printStrackTrace(); // shows you the case of the exception, not where it was last re-thrown.
}
}
例外のスタックトレースが「新しい」の操作に対応して、何もない。
と思うことを想定することはできませんスをインスタンス化中に例外を除きの過程で廃棄してしまうので、なぜ支払う価格を取得しスタックトレース。
では難しいのではないでしょうかを再現のスタックトレースを投入するかということだけを送信し、オブジェクトです。
の例外にすべきである設定の前に投げ、そのインスタンス生成のスタックトレース.
更新:
話ができ fillInStackTrace()
これで解決。