📄 tij311.htm
字号:
<font color=#004488>"MyException2: Detail Message: 47 Originated in h()"</font>,
<font color=#004488>"%% \tat ExtraFeatures.h\\(.*\\)"</font>,
<font color=#004488>"%% \tat ExtraFeatures.main\\(.*\\)"</font>,
<font color=#004488>"e.val() = 47"</font>
});
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>A field <b>i</b> has been added, along with a method that reads that value and an additional constructor that sets it. In addition, <b>Throwable.getMessage( )</b> has been overridden to produce a more interesting detail message. <b>getMessage( ) </b>is something like <b>toString( ) </b>for exception classes. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1537" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Since an exception is just another kind of object, you can continue this process of embellishing the power of your exception classes. Keep in mind, however, that all this dressing-up might be lost on the client programmers using your packages, since they might simply look for the exception to be thrown and nothing more. (That’s the way most of the Java library exceptions are used.) <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1538" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc312374116"></a><a name="_Toc375545367"></a><a name="_Toc24775704"></a><a name="Heading8521"></a>The
exception specification<br></h2>
<p><a name="Index802"></a><a name="Index803"></a>In Java, you’re encouraged to inform the client programmer, who calls your method, of the exceptions that might be thrown from your method. This is civilized, because the caller can know exactly what code to write to catch all potential exceptions. Of course, if source code is available, the client programmer could hunt through and look for <b>throw</b> statements, but often a library doesn’t come with sources. To prevent this from being a problem, Java provides syntax (and <i>forces </i>you to use that syntax) to allow you to politely tell the client programmer what exceptions this method throws, so the client programmer can handle them. This is the <i>exception specification</i> and it’s part of the method declaration, appearing after the argument list. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1539" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The exception specification uses an additional keyword, <b>throws</b>, followed by a list of all the potential exception types. So your method definition might look like this:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>void</font> f() <font color=#0000ff>throws</font> TooBig, TooSmall, DivZero { <font color=#009900>//... </font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>If you say<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>void</font> f() { <font color=#009900>// ...</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>it means that no exceptions are thrown from the method (<i>except </i>for the exceptions inherited from <b>RuntimeException</b>, which can be thrown anywhere without exception specifications—this will be described later). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1540" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>You can’t lie about an exception specification. If the code within your method causes exceptions, but your method doesn’t handle them, the compiler will detect this and tell you that you must either handle the exception or indicate with an exception specification that it may be thrown from your method. By enforcing exception specifications from top to bottom, Java guarantees that a certain level of exception correctness can be ensured at compile time. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1541" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>There is one place you can lie: You can claim to throw an exception that you really don’t. The compiler takes your word for it, and forces the users of your method to treat it as if it really does throw that exception. This has the beneficial effect of being a placeholder for that exception, so you can actually start throwing the exception later without requiring changes to existing code. It’s also important for creating <b>abstract</b> base classes and <b>interface</b>s whose derived classes or implementations may need to throw exceptions. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1542" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Exceptions that are checked and enforced at compile time are called <i>checked exceptions</i>. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0508" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc312374118"></a><a name="_Toc375545368"></a><a name="_Toc24775705"></a><a name="Heading8533"></a>Catching
any exception<br></h2>
<p><a name="Index804"></a><a name="Index805"></a>It is possible to create a handler that catches any type of exception. You do this by catching the base-class exception type <b>Exception</b> (there are other types of base exceptions, but <b>Exception</b> is the base that’s pertinent to virtually all programming activities):<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>catch</font>(Exception e) {
System.err.println(<font color=#004488>"Caught an exception"</font>);
}</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>This will catch any exception, so if you use it you’ll want to put it at the <i>end</i> of your list of handlers to avoid preempting any exception handlers that might otherwise follow it. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1543" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Since the <b>Exception</b> class is the base of all the exception classes that are important to the programmer, you don’t get much specific information about the exception, but you can call the methods that come from <i>its</i> base type <a name="Index806"></a><a name="Index807"></a><b>Throwable</b>:<br></p>
<p><b>String getMessage( )</b><br><b>String getLocalizedMessage( )</b><br>Gets the detail message, or a message adjusted for this particular locale. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1544" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><b>String toString( )</b><br>Returns a short description of the Throwable, including the detail message if there is one. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1545" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><b>void printStackTrace( ) </b><br><a name="Index808"></a><b>void printStackTrace(PrintStream)</b><br><b>void printStackTrace(java.io.PrintWriter) </b><br>Prints the Throwable and the Throwable’s call stack trace. The call stack shows the sequence of method calls that brought you to the point at which the exception was thrown. The first version prints to standard error, the second and third prints to a stream of your choice (in Chapter 12, you’ll understand why there are two types of streams). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1546" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><b>Throwable fillInStackTrace( )</b><br>Records information within this <b>Throwable </b>object about the current state of the stack frames. Useful when an application is rethrowing an error or exception (more about this shortly). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1547" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>In addition, you get some other methods from <b>Throwable</b>’s base type <b>Object</b> (everybody’s base type). The one that might come in handy for exceptions is <a name="Index809"></a><a name="Index810"></a><b>getClass( )</b>, which returns an object representing the class of this object. You can in turn query this <b>Class</b> object for its name with <b>getName( )</b>. You can also do more sophisticated things with <b>Class</b> objects that aren’t necessary in exception handling. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1548" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Here’s an example that shows the use of the basic <b>Exception</b> methods:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c09:ExceptionMethods.java</font>
<font color=#009900>// Demonstrating the Exception Methods.</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> ExceptionMethods {
<font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
<font color=#0000ff>try</font> {
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> Exception(<font color=#004488>"My Exception"</font>);
} <font color=#0000ff>catch</font>(Exception e) {
System.err.println(<font color=#004488>"Caught Exception"</font>);
System.err.println(<font color=#004488>"getMessage():"</font> + e.getMessage());
System.err.println(<font color=#004488>"getLocalizedMessage():"</font> +
e.getLocalizedMessage());
System.err.println(<font color=#004488>"toString():"</font> + e);
System.err.println(<font color=#004488>"printStackTrace():"</font>);
e.printStackTrace();
}
monitor.expect(<font color=#0000ff>new</font> String[] {
<font color=#004488>"Caught Exception"</font>,
<font color=#004488>"getMessage():My Exception"</font>,
<font color=#004488>"getLocalizedMessage():My Exception"</font>,
<font color=#004488>"toString():java.lang.Exception: My Exception"</font>,
<font color=#004488>"printStackTrace():"</font>,
<font color=#004488>"java.lang.Exception: My Exception"</font>,
<font color=#004488>"%% \tat ExceptionMethods.main\\(.*\\)"</font>
});
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>You can see that the methods provide successively more information—each is effectively a superset of the previous one. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1549" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc312374119"></a><a name="_Toc375545369"></a><a name="_Toc24775706"></a><a name="Heading8578"></a>Rethrowing
an exception<br></h3>
<p><a name="Index811"></a><a name="Index812"></a>Sometimes you’ll want to rethrow the exception that you just caught, particularly when you use <b>Exception</b> to catch any exception. Since you already have the reference to the current exception, you can simply rethrow that reference:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>catch</font>(Exception e) {
System.err.println(<font color=#004488>"An exception was thrown"</font>);
<font color=#0000ff>throw</font> e;
}</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>Rethrowing an exception causes it to go to the exception handlers in the next-higher context. Any further <b>catch</b> clauses for the same <b>try</b> block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1550" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>If you simply rethrow the current exception, the information that you print about that exception in <a name="Index813"></a><a name="Index814"></a><b>printStackTrace( ) </b>will pertain to the exception’s origin, not the place where you rethrow it. If you want to install new stack trace information, you can do so by calling <a name="Index815"></a><a name="Index816"></a><b>fillInStackTrace( )</b>, which returns a <b>Throwable</b> object that it creates by stuffing the current stack information into the old exception object. Here’s what it looks like: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0145" title="Send BackTalk Comment">Feedback</a></font><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c09:Rethrowing.java</font>
<font color=#009900>// Demonstrating fillInStackTrace()</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Rethrowing {
<font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
<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(<font color=#004488>"originating the exception in f()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> Exception(<font color=#004488>"thrown from f()"</font>);
}
<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.err.println(<font color=#004488>"Inside g(),e.printStackTrace()"</font>);
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.err.println(
<font color=#004488>"Caught in main, e.printStackTrace()"</font>);
e.printStackTrace();
}
monitor.expect(<font color=#0000ff>new</font> String[] {
<font color=#004488>"originating the exception in f()"</font>,
<font color=#004488>"Inside g(),e.printStackTrace()"</font>,
<font color=#004488>"java.lang.Exception: thrown from f()"</font>,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -