📄 chap10.htm
字号:
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></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Because of
<B>fillInStackTrace( )</B>, line 18 becomes the new
<A NAME="Index1088"></A>point of origin of the exception.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I44'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I45>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The class <B>Throwable</B> must appear in
the exception specification for <B>g( )</B> and <B>main( )</B> because
<B>fillInStackTrace( )</B> produces a reference to a <B>Throwable</B>
object. Since <A NAME="Index1089"></A><B>Throwable</B> is a base class of
<B>Exception</B>, it’s possible to get an object that’s a
<B>Throwable</B> but <I>not</I> an <B>Exception</B>, so the handler for
<B>Exception</B> in <B>main( ) </B>might miss it. To make sure everything
is in order, the compiler forces an exception specification for
<B>Throwable</B>. For example, the exception in the following program is
<I>not</I> caught in <B>main( )</B>:
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I45'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I46>
</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c10: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.err.println(<font color=#004488>"Caught in main()"</font>);
}
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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 <B>fillInStackTrace( )</B>—the information
about the original site of the exception is lost, and what you’re left
with is the information pertaining to the new <B>throw</B>:
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I46'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I47>
</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c10:RethrowNew.java</font>
<font color=#009900>// Rethrow a different object </font>
<font color=#009900>// from the one that was caught.</font>
<font color=#0000ff>class</font> OneException <font color=#0000ff>extends</font> Exception {
<font color=#0000ff>public</font> OneException(String s) { <font color=#0000ff>super</font>(s); }
}
<font color=#0000ff>class</font> TwoException <font color=#0000ff>extends</font> Exception {
<font color=#0000ff>public</font> TwoException(String s) { <font color=#0000ff>super</font>(s); }
}
<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> OneException {
System.out.println(
<font color=#004488>"originating the exception in f()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> OneException(<font color=#004488>"thrown from f()"</font>);
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args)
<font color=#0000ff>throws</font> TwoException {
<font color=#0000ff>try</font> {
f();
} <font color=#0000ff>catch</font>(OneException e) {
System.err.println(
<font color=#004488>"Caught in main, e.printStackTrace()"</font>);
e.printStackTrace(System.err);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> TwoException(<font color=#004488>"from main()"</font>);
}
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output is:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>originating the exception in f()
Caught in main, e.printStackTrace()
OneException: thrown from f()
at RethrowNew.f(RethrowNew.java:17)
at RethrowNew.main(RethrowNew.java:22)
Exception in thread <font color=#004488>"main"</font> TwoException: from main()
at RethrowNew.main(RethrowNew.java:27)</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The final exception knows only that it
came from <B>main( )</B>, and not from <B>f( )</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I47'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I48>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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 <B>new</B>, so the garbage collector
automatically cleans them all up.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I48'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I49>
</FONT><A NAME="_Toc375545370"></A><A NAME="_Toc481064723"></A><BR></P></DIV>
<A NAME="Heading342"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Standard Java exceptions</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The Java class <B>Throwable</B> describes
anything that can be thrown as an exception. There are two general types of
<B>Throwable</B> objects (“types of” = “inherited
from”). <A NAME="Index1090"></A><B>Error</B> represents compile-time and
system errors that you don’t worry about catching (except in special
cases). <A NAME="Index1091"></A><B>Exception</B> is the basic type that can be
thrown from any of the standard Java library class methods and from your methods
and run-time accidents. So the Java programmer’s base type of interest is
<B>Exception</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I49'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I50>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The best way to get an overview of the
exceptions is to browse the HTML Java documentation that you can download from
<I>java.sun.com.</I> It’s worth doing this once just to get a feel for the
various exceptions, but you’ll soon see that there isn’t anything
special between one exception and the next except for the name. Also, the number
of exceptions in Java keeps expanding; basically it’s pointless to print
them in a book. Any new library you get from a third-party vendor will probably
have its own exceptions as well. The important thing to understand is the
concept and what you should do with the exceptions.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I50'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I51>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The basic idea is that the name of the
exception represents the problem that occurred, and the exception name is
intended to be relatively self-explanatory. The exceptions are not all defined
in <B>java.lang</B>; some are created to support other libraries such as
<B>util</B>, <B>net,</B> and <B>io</B>, which you can see from their full class
names or what they are inherited from. For example, all I/O exceptions are
inherited from <B>java.io.IOException</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I51'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I52>
</FONT><A NAME="_Toc375545372"></A><A NAME="_Toc481064724"></A><BR></P></DIV>
<A NAME="Heading343"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
The special case of RuntimeException</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first example in this chapter
was</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>if</font>(t == <font color=#0000ff>null</font>)
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> NullPointerException();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It can be a bit horrifying to think that
you must check for <B>null</B> on every reference that is passed into a method
(since you can’t know if the caller has passed you a valid reference).
Fortunately, you don’t—this is part of the standard run-time
checking that Java performs for you, and if any call is made to a <B>null</B>
reference, Java will automatically throw a
<A NAME="Index1092"></A><A NAME="Index1093"></A><B>NullPointerException</B>. So
the above bit of code is always superfluous.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I52'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I53>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There’s a whole group of exception
types that are in this category. They’re always thrown automatically by
Java and you don’t need to include them in your exception specifications.
Conveniently enough, they’re all grouped together by putting them under a
single base class called <B>RuntimeException</B>, which is a perfect example of
inheritance: it establishes a family of types that have some characteristics and
behaviors in common. Also, you never need to write an exception specification
saying that a method might throw a <B>RuntimeException</B>, since that’s
just assumed. Because they indicate bugs, you virtually never catch a
<A NAME="Index1094"></A><A NAME="Index1095"></A><B>RuntimeException</B>—it’s
dealt with automatically. If you were forced to check for
<B>RuntimeException</B>s your code could get messy. Even though you don’t
typically catch <B>RuntimeExceptions</B>,<B> </B>in your own packages you might
choose to throw some of the <B>RuntimeException</B>s.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I53'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I54>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What happens when you don’t catch
such exceptions? Since the compiler doesn’t enforce exception
specifications for these, it’s quite plausible that a
<B>RuntimeException</B> could percolate all the way out to your <B>main( )
</B>method without being caught. To see what happens in this case, try the
following example:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c10:NeverCaught.java</font>
<font color=#009900>// Ignoring RuntimeExceptions.</font>
<font color=#0000ff>public</font> <font color=#0000ff>class</font> NeverCaught {
<font color=#0000ff>static</font> <font color=#0000ff>void</font> f() {
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> RuntimeException(<font color=#004488>"From f()"</font>);
}
<font color=#0000ff>static</font> <font color=#0000ff>void</font> g() {
f();
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
g();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can already see that a
<B>RuntimeException </B>(or anything inherited from it) is a special case, since
the compiler doesn’t require an exception specification for these types.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER10_I54'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER10_I55>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output is:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Exception in thread <font color=#004488>"main"</font>
java.lang.RuntimeException: From f()
at NeverCaught.f(NeverCaught.java:9
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -