それは、「安全」の定義によって異なります。この例外は、誤解を招くようなスタック トレースを提供しますが、これは「安全」とは言えません。検討:
public class ThrowTest {
private static Exception e = new Exception("t1"); // Line 2
public static final void main(String[] args) {
ThrowTest tt;
tt = new ThrowTest();
try {
tt.t1();
}
catch (Exception ex) {
System.out.println("t1:");
ex.printStackTrace(System.out);
}
try {
tt.t2(); // Line 16
}
catch (Exception ex) {
System.out.println("t2:");
ex.printStackTrace(System.out);
}
}
private void t1()
throws Exception {
throw this.e;
}
private void t2()
throws Exception {
throw new Exception("t2"); // Line 31
}
}
次の出力があります。
$ java ThrowTest
t1:
java.lang.Exception: t1
ThrowTest.<clinit>(ThrowTest.java:2) で
t2:
java.lang.Exception: t2
ThrowTest.t2 (ThrowTest.java:31) で
ThrowTest.main で (ThrowTest.java:16)
t1
最初のテスト ケースのスタック トレースからメソッドが完全に欠落していることに注意してください。有用なコンテキスト情報はまったくありません。
これで、スローの直前に を使用してその情報を入力できます。fillInStackTrace
this.e.fillInStackTrace();
throw this.e;
...しかし、それは自分のために仕事をしているだけです (あなたが時々忘れる仕事)。それだけではまったくメリットがありません。また、すべての例外でそれができるわけではありません (一部の例外では、スタック トレースが読み取り専用になります)。
コメントの他の場所で、これは「コードの重複」を避けるためだと言っています。例外ビルダー関数を使用する方がはるかに優れています。
private IllegalStateException buildISE() {
return new IllegalStateException("le sophisticated way");
}
(お好みでstatic final
どうぞ。)
そして、次のように投げます:
throw buildISE();
これにより、誤解を招くスタック トレースや不要な Exception インスタンスを発生させることなく、コードの重複を回避できます。
これを上記に適用すると、次のようになります。
public class ThrowTest {
public static final void main(String[] args) {
ThrowTest tt;
tt = new ThrowTest();
try {
tt.t1(); // Line 8
}
catch (Exception ex) {
System.out.println("t1:");
ex.printStackTrace(System.out);
}
try {
tt.t2(); // Line 15
}
catch (Exception ex) {
System.out.println("t2:");
ex.printStackTrace(System.out);
}
}
private static final Exception buildEx() {
return new Exception("t1"); // Line 24
}
private void t1()
throws Exception {
throw buildEx(); // Line 29
}
private void t2()
throws Exception {
throw new Exception("t2"); // Line 34
}
}
$ java ThrowTest
t1:
java.lang.Exception: t1
ThrowTest.buildEx(ThrowTest.java:24) で
ThrowTest.t1 (ThrowTest.java:29) で
ThrowTest.main で (ThrowTest.java:8)
t2:
java.lang.Exception: t2
ThrowTest.t2 で (ThrowTest.java:34)
ThrowTest.main で (ThrowTest.java:15)