这取决于您对“安全”的定义。该异常会产生误导性的堆栈跟踪,我不会称之为“安全”。考虑:
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();
这避免了代码重复,而不会误导堆栈跟踪和不必要的异常实例。
以下是适用于上述内容的内容:
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)