📄 tij0098.html
字号:
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Rethrowing {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> f() <font color="#0000ff">throws</font> Exception {
System.out.println(
"originating the exception in f()");
<font color="#0000ff">throw</font> <font color="#0000ff">new</font> Exception("thrown from f()");
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> g() <font color="#0000ff">throws</font> Throwable {
<font color="#0000ff">try</font> {
f();
} <font color="#0000ff">catch</font>(Exception e) {
System.out.println(
"Inside g(), e.printStackTrace()");
e.printStackTrace();
<font color="#0000ff">throw</font> e; <font color="#009900">// 17</font>
<font color="#009900">// throw e.fillInStackTrace(); // 18</font>
}
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font>
main(String[] args) <font color="#0000ff">throws</font> Throwable {
<font color="#0000ff">try</font> {
g();
} <font color="#0000ff">catch</font>(Exception e) {
System.out.println(
"Caught in main, e.printStackTrace()");
e.printStackTrace();
}
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
important line numbers are marked inside of comments. With line 17 un-commented
(as shown), the output is:
</FONT><P></DIV>
<font color="#990000"><PRE>originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.f(Rethrowing.java:8)
at Rethrowing.g(Rethrowing.java:12)
at Rethrowing.main(Rethrowing.java:24)
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.f(Rethrowing.java:8)
at Rethrowing.g(Rethrowing.java:12)
at Rethrowing.main(Rethrowing.java:24) </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">So
the exception stack trace always remembers its true point of origin, no matter
how many times it gets rethrown.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">With
line 17 commented and line 18 un-commented,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillInStackTrace( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is used instead, and the result is:
</FONT><P></DIV>
<font color="#990000"><PRE>originating the exception in f()
Inside g(), e.printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.f(Rethrowing.java:8)
at Rethrowing.g(Rethrowing.java:12)
at Rethrowing.main(Rethrowing.java:24)
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.g(Rethrowing.java:18)
at Rethrowing.main(Rethrowing.java:24) </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Because
of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillInStackTrace( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
line 18 becomes the new <A NAME="Index938"></A>point
of origin of the exception.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Throwable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
must appear in the exception specification for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>g( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
because
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillInStackTrace( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
produces a handle to a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Throwable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object. Since <A NAME="Index939"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Throwable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a base class of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Exception</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
it’s possible to get an object that’s a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Throwable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
but
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Exception</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so the handler for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Exception</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">might
miss it. To make sure everything is in order, the compiler forces an exception
specification for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Throwable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
For example, the exception in the following program is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
caught in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: ThrowOut.java</font>
<font color="#0000ff">public</font> <font color="#0000ff">class</font> ThrowOut {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font>
main(String[] args) <font color="#0000ff">throws</font> Throwable {
<font color="#0000ff">try</font> {
<font color="#0000ff">throw</font> <font color="#0000ff">new</font> Throwable();
} <font color="#0000ff">catch</font>(Exception e) {
System.out.println("Caught in main()");
}
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It’s
also possible to rethrow a different exception from the one you caught. If you
do this, you get a similar effect as when you use
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fillInStackTrace( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
the information about the original site of the exception is lost, and what
you’re left with is the information pertaining to the new
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>throw</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: RethrowNew.java</font>
<font color="#009900">// Rethrow a different object from the one that</font>
<font color="#009900">// was caught</font>
<font color="#0000ff">public</font> <font color="#0000ff">class</font> RethrowNew {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> f() <font color="#0000ff">throws</font> Exception {
System.out.println(
"originating the exception in f()");
<font color="#0000ff">throw</font> <font color="#0000ff">new</font> Exception("thrown from f()");
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#0000ff">try</font> {
f();
} <font color="#0000ff">catch</font>(Exception e) {
System.out.println(
"Caught in main, e.printStackTrace()");
e.printStackTrace();
<font color="#0000ff">throw</font> <font color="#0000ff">new</font> NullPointerException("from main");
}
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
output is:
</FONT><P></DIV>
<font color="#990000"><PRE>originating the exception in f()
Caught in main, e.printStackTrace()
java.lang.Exception: thrown from f()
at RethrowNew.f(RethrowNew.java:8)
at RethrowNew.main(RethrowNew.java:13)
java.lang.NullPointerException: from main
at RethrowNew.main(RethrowNew.java:18) </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
final exception knows only that it came from
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and not from
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Note that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Throwable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
isn’t necessary in any of the exception specifications.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
never have to worry about cleaning up the previous exception, or any exceptions
for that matter. They’re all heap-based objects created with
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>new</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so the garbage collector automatically cleans them all up.
</FONT><a name="_Toc375545370"></a><a name="_Toc408018597"></a><P></DIV>
<HR><DIV ALIGN=LEFT><A NAME="fn42" HREF="#fnB42">[42]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
This is a significant improvement over C++ exception handling, which
doesn’t catch violations of exception specifications until run time, when
it’s not very useful.
</FONT><P></DIV>
<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0097.html">Prev</a> | <a href="tij0099.html">Next</a>
</div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -