⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij311.htm

📁 这也是我们java老师给我们的thinking in java的一些资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<!--
This document was converted from RTF source: 
By r2net 5.8 r2netcmd Windows 
See http://www.logictran.com
-->
<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Thinking in Java, 3rd ed. Revision 4.0: 9: Error Handling  with Exceptions</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css"></head>

<body >
   <CENTER>     <a href="http://www.MindView.net">     <img src="mindview.gif" alt="MindView Inc." BORDER = "0"></a>     <Font FACE="Verdana, Tahoma, Arial, Helvetica, Sans">     <h2>Thinking in Java, 3<sup>rd</sup> ed. Revision 4.0</h2>     <FONT size = "-1"><br>     [ <a href="README.txt">Viewing Hints</a> ]     [ <a href="http://www.mindview.net/Books/TIJ/">Book Home Page</a> ]     [ <a href="http://www.mindview.net/Etc/MailingList.html">Free Newsletter</a> ] <br>     [ <a href="http://www.mindview.net/Seminars">Seminars</a> ]     [ <a href="http://www.mindview.net/CDs">Seminars on CD ROM</a> ]     [ <a href="http://www.mindview.net/Services">Consulting</a> ] <br><br>     </FONT></FONT>   </CENTER> 
<font face="Georgia"><div align="CENTER"><a href="TIJ310.htm" target="RightFrame"><img src="./prev.gif" alt="Previous " border="0"></a>
<a href="TIJ312.htm" target="RightFrame"><img src="./next.gif" alt="Next " border="0"></a>

<a href="TIJ3_t.htm"><img src="./first.gif" alt="Title Page " border="0"></a>
<a href="TIJ3_i.htm"><img src="./index.gif" alt="Index " border="0"></a>
<a href="TIJ3_c.htm"><img src="./contents.gif" alt="Contents " border="0"></a>
</div>
<hr>

<h1>
<a name="_Toc375545404"></a><a name="_Toc24272648"></a><a name="_Toc24775697"></a><a name="Heading8318"></a>9:
Error Handling <br>with Exceptions</h1>
<p class="Intro">The basic philosophy of Java is that &#147;badly formed code will not be run.&#148;<br></p>
<p>The ideal time to catch an error is at compile time, before you even try to run the program. However, not all errors can be detected at compile time. The rest of the problems must be handled at run time through some formality that allows the originator of the error to pass appropriate information to a recipient who will know how to handle the difficulty properly. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1508" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index778"></a><a name="Index779"></a>C and other earlier languages often had multiple error-handling schemes, and these were generally established by convention and not as part of the programming language. Typically, you returned a special value or set a flag, and the recipient was supposed to look at the value or the flag and determine that something was amiss. However, as the years passed, it was discovered that programmers who use a library tend to think of themselves as invincible&#151;as in, &#147;Yes, errors might happen to others, but not in <i>my</i> code.&#148; So, not too surprisingly, they wouldn&#146;t check for the error conditions (and sometimes the error conditions were too silly to check for<sup><a name="fnB40" href="#fn40">[40]</a></sup>). If you <i>were</i> thorough enough to check for an error every time you called a method, your code could turn into an unreadable nightmare. Because programmers could still coax systems out of these languages, they were resistant to admitting the truth: that this approach to handling errors was a major limitation to creating large, robust, maintainable programs. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1509" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The solution is to take the casual nature out of error handling and to enforce formality. This actually has a long history, because implementations of <i>exception handling</i> go back to operating systems in the 1960s, and even to BASIC&#146;s &#147;<b>on error goto</b>.&#148; But C++ exception handling was based on Ada, and Java&#146;s is based primarily on C++ (although it looks more like that in Object Pascal). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1510" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The word &#147;exception&#148; is meant in the sense of &#147;I take exception to that.&#148; At the point where the problem occurs, you might not know what to do with it, but you do know that you can&#146;t just continue on merrily; you must stop, and somebody, somewhere, must figure out what to do. But you don&#146;t have enough information in the current context to fix the problem. So you hand the problem out to a higher context where someone is qualified to make the proper decision (much like a chain of command). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1511" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The other rather significant benefit of exceptions is that they clean up error handling code. Instead of checking for a particular error and dealing with it at multiple places in your program, you no longer need to check at the point of the method call (since the exception will guarantee that someone catches it). And, you need to handle the problem in only one place, the so-called <a name="Index780"></a><i>exception handler</i>. This saves you code, and it separates the code that describes what you want to do from the code that is executed when things go awry. In general, reading, writing, and debugging code becomes much clearer with exceptions than when using the old way of error handling. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1512" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Because exception handling is the only official way that Java reports errors, and it is enforced by the Java compiler, there are only so many examples that can be written in this book without learning about exception handling. This chapter introduces you to the code you need to write to properly handle exceptions, and the way you can generate your own exceptions if one of your methods gets into trouble. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1513" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc375545362"></a><a name="_Toc24775698"></a><a name="Heading8327"></a>Basic
exceptions</h2>
<p>An <a name="Index781"></a><i>exceptional condition</i> is a problem that prevents the continuation of the method or scope that you&#146;re in. It&#146;s important to distinguish an exceptional condition from a normal problem, in which you have enough information in the current context to somehow cope with the difficulty. With an exceptional condition, you cannot continue processing because you don&#146;t have the information necessary to deal with the problem <i>in the current context</i>. All you can do is jump out of the current context and relegate that problem to a higher context. This is what happens when you throw an exception. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1514" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Division is a simple example. If you&#146;re about to divide by zero, it&#146;s worth checking for that condition. But what does it mean that the denominator is zero? Maybe you know, in the context of the problem you&#146;re trying to solve in that particular method, how to deal with a zero denominator. But if it&#146;s an unexpected value, you can&#146;t deal with it and so must throw an exception rather than continuing along that execution path. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1515" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>When you throw an exception, several things happen. First, the exception object is created in the same way that any Java object is created: on the heap, with <a name="Index782"></a><b>new</b>. Then the current path of execution (the one you couldn&#146;t continue) is stopped and the reference for the exception object is ejected from the current context. At this point the exception handling mechanism takes over and begins to look for an appropriate place to continue executing the program. This appropriate place is the <i>exception handler,</i> whose job is to recover from the problem so the program can either try another tack or just continue. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1516" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>As a simple example of throwing an exception, consider an object reference called <b>t</b>. It&#146;s possible that you might be passed a reference that hasn&#146;t been initialized, so you might want to check before trying to call a method using that object reference. You can send information about the error into a larger context by creating an object representing your information and &#147;throwing&#148; it out of your current context. This is called <i>throwing an exception.</i> Here&#146;s what it looks like:<br></p>

<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><p><br></p>
<p>This throws the exception, which allows you&#151;in the current context&#151;to abdicate responsibility for thinking about the issue further. It&#146;s just magically handled somewhere else. Precisely <i>where </i>will be shown shortly. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1517" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc375545363"></a><a name="_Toc24775699"></a><a name="Heading8336"></a>Exception
arguments<br></h3>
<p><a name="Index783"></a><a name="Index784"></a>Like any object in Java, you always create exceptions on the heap using <b>new</b>, which allocates storage and calls a constructor. There are two constructors in all standard exceptions; The first is the default constructor, and the second takes a string argument so you can place pertinent information in the exception:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>  <font color=#0000ff>throw</font> <font color=#0000ff>new</font> NullPointerException(<font color=#004488>"t = null"</font>);</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>This string can later be extracted using various methods, as you&#146;ll see. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1518" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The keyword <a name="Index785"></a><b>throw</b> causes a number of relatively magical things to happen. Typically, you&#146;ll first use <b>new</b> to create<b> </b>an object that represents the error condition. You give the resulting reference to <b>throw</b>. The object is, in effect, &#147;returned&#148; from the method, even though that object type isn&#146;t normally what the method is designed to return. A simplistic way to think about exception handling is as a different kind of return mechanism, although you get into trouble if you take that analogy too far. You can also exit from ordinary scopes by throwing an exception. But a value is returned, and the method or scope exits. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1519" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Any similarity to an ordinary return from a method ends here, because <i>where</i> you return is someplace completely different from where you return for a normal method call. (You end up in an appropriate exception handler that might be far&#151;many levels away on the call stack&#151;from where the exception was thrown.) <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1520" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>In addition, you can throw any type of <b>Throwable</b> (the exception root class) object that you want. Typically, you&#146;ll throw a different class of exception for each different type of error. The information about the error is represented both inside the exception object and implicitly in the name of the exception class, so someone in the bigger context can figure out what to do with your exception. (Often, the only information is the type of exception, and nothing meaningful is stored within the exception object.) <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1521" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc305593298"></a><a name="_Toc305628770"></a><a name="_Toc312374113"></a><a name="_Toc375545364"></a><a name="_Toc24775700"></a><a name="Heading8344"></a>Catching
an exception<br></h2>
<p><a name="Index786"></a><a name="Index787"></a>If a method throws an exception, it must assume that exception will be &#147;caught&#148; and dealt with. One of the advantages of exception handling is that it allows you to concentrate on the problem you&#146;re trying to solve in one place, and then deal with the errors from that code in another place. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1522" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>To see how an exception is caught, you must first understand the concept of a <a name="Index788"></a><a name="Index789"></a><i>guarded region.</i> This is a section of code that might produce exceptions and is followed by the code to handle those exceptions. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1523" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc312374114"></a><a name="_Toc375545365"></a><a name="_Toc24775701"></a><a name="Heading8347"></a>The
<b>try</b> block</h3>
<p>If you&#146;re inside a method and you throw an exception (or another method you call within this method throws an exception), that method will exit in the process of throwing. If you don&#146;t want a <b>throw </b>to exit the method, you can set up a special block within that method to capture the exception. This is called the <i>try</i> <i>block</i> because you &#147;try&#148; your various method calls there. The try block is an ordinary scope preceded by the keyword <a name="Index790"></a><a name="Index791"></a><b>try</b>: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0144" title="Send BackTalk Comment">Feedback</a></font><br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>try</font> {
  <font color=#009900>// Code that might generate exceptions</font>
}</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>If you were checking for errors carefully in a programming language that didn&#146;t support exception handling, you&#146;d have to surround every method call with setup and error testing code, even if you call the same method several times. With exception handling, you put everything in a try block and capture all the exceptions in one place. This means your code is much easier to write and read because the goal of the code is not confused with the error checking. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1524" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc312374115"></a><a name="_Toc375545366"></a><a name="_Toc24775702"></a><a name="Heading8354"></a>Exception
handlers</h3>
<p>Of course, the thrown exception must end up someplace. This &#147;place&#148; is the <i>exception handler</i><a name="Index792"></a><a name="Index793"></a><i>,</i> and there&#146;s one for every exception type you want to catch. Exception handlers immediately follow the try block and are denoted by the keyword <b>catch</b>:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>try</font> {
  <font color=#009900>// Code that might generate exceptions</font>
} <font color=#0000ff>catch</font>(Type1 id1) {
  <font color=#009900>// Handle exceptions of Type1</font>
} <font color=#0000ff>catch</font>(Type2 id2) {
  <font color=#009900>// Handle exceptions of Type2</font>
} <font color=#0000ff>catch</font>(Type3 id3) {
  <font color=#009900>// Handle exceptions of Type3</font>
}

<font color=#009900>// etc...</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>Each catch clause (exception handler) is like a little method that takes one and only one argument of a particular type. The identifier (<b>id1</b>, <b>id2</b>, and so on) can be used inside the handler, just like a method argument. Sometimes you never use the identifier because the type of the exception gives you enough information to deal with the exception, but the identifier must still be there. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1525" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The handlers must appear directly after the try block. If an exception is thrown, the exception handling mechanism goes hunting for the first handler with an argument that matches the type of the exception. Then it enters that catch clause, and the exception is considered handled. The search for handlers stops once the catch clause is finished. Only the matching catch clause executes; it&#146;s not like a <b>switch</b> statement in which you need a <b>break</b> after each <b>case</b> to prevent the remaining ones from executing. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1526" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Note that within the try block, a number of different method calls might generate the same exception, but you need only one handler. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1527" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h4>
<a name="Heading8371"></a>Termination vs. resumption<br></h4>
<p><a name="Index795"></a><a name="Index796"></a><a name="Index797"></a>There are two basic models in exception handling theory. In <i>termination</i> (which is what Java and C++ support), you assume that the error is so critical that there&#146;s no way to get back to where the exception occurred. Whoever threw the exception decided that there was no way to salvage the situation, and they don&#146;t <i>want</i> to come back. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1528" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The alternative is called <i>resumption</i>. It means that the exception handler is expected to do something to rectify the situation, and then the faulting method is retried, presuming success the second time. If you want resumption, it means you still hope to continue execution after the exception is handled. In this case, your exception is more like a method call&#151;which is how you should set up situations in Java in which you want resumption-like behavior. (That is, don&#146;t throw an exception; call a method that fixes the problem.) Alternatively, place your <b>try</b> block inside a <b>while</b> loop that keeps reentering the <b>try</b> block until the result is satisfactory. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1529" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Historically, programmers using operating systems that supported resumptive exception handling eventually ended up using termination-like code and skipping resumption. So although resumption sounds attractive at first, it isn&#146;t quite so useful in practice. The dominant reason is probably the <a name="Index798"></a><i>coupling </i>that results; your handler must often be aware of where the exception is thrown, and contain nongeneric code specific to the throwing location. This makes the code difficult to write and maintain, especially for large systems where the exception can be generated from many points. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1530" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc375545373"></a><a name="_Toc24775703"></a><a name="Heading8375"></a>Creating
your own exceptions</h2>
<p>You&#146;re not stuck using the existing Java exceptions. The JDK exception hierarchy can&#146;t foresee all the errors you might want to report, so you can create your own to denote a special problem that your library might encounter. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap10_1531" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index799"></a>To create your own exception class, you must inherit from an existing exception class, preferably one that is close in meaning to your new exception (although this is often not possible). The most trivial way to create a new type of exception is just to let the compiler create the default constructor for you, so it requires almost no code at all:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c09:SimpleExceptionDemo.java</font>
<font color=#009900>// Inheriting your own exceptions.</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;

<font color=#0000ff>class</font> SimpleException <font color=#0000ff>extends</font> Exception {}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> SimpleExceptionDemo {
  <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>void</font> f() <font color=#0000ff>throws</font> SimpleException {
    System.out.println(<font color=#004488>"Throw SimpleException from f()"</font>);
    <font color=#0000ff>throw</font> <font color=#0000ff>new</font> SimpleException();
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    SimpleExceptionDemo sed = <font color=#0000ff>new</font> SimpleExceptionDemo();
    <font color=#0000ff>try</font> {
      sed.f();
    } <font color=#0000ff>catch</font>(SimpleException e) {
      System.err.println(<font color=#004488>"Caught it!"</font>);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -