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

📄 chapter09.html

📁 java 是一个很好的网络开发环境。由于它是通过解释的方法
💻 HTML
📖 第 1 页 / 共 5 页
字号:
The try block</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you&#8217;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&#8217;t
want a <B>throw </B>to leave a method, you can set up a special block within
that method to capture the exception. This is called the <I>try</I>
<I>block<A NAME="Index913"></A><A NAME="Index914"></A></I> because you
&#8220;try&#8221; your various method calls there. The try block is an ordinary
scope, preceded by the keyword <B>try</B>:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>try</font> {
  <font color=#009900>// Code that might generate exceptions</font>
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you were checking for errors
carefully in a programming language that didn&#8217;t support exception
handling, you&#8217;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 a lot easier to write and easier to read
because the goal of the code is not confused with the error
checking.</FONT><A NAME="_Toc312374115"></A><A NAME="_Toc375545366"></A><A NAME="_Toc408018593"></A><BR></P></DIV>
<A NAME="Heading285"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Exception handlers</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Of course, the thrown exception
must end up someplace. This &#8220;place&#8221; is the <I>exception
handler<A NAME="Index915"></A><A NAME="Index916"></A></I>, and there&#8217;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<A NAME="Index917"></A></B>:</FONT><BR></P></DIV>

<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>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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&#8217;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><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that, within the try block, a
number of different method calls might generate the same exception, but you need
only one handler.</FONT><BR></P></DIV>
<A NAME="Heading286"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Termination vs.
resumption<BR><A NAME="Index918"></A><A NAME="Index919"></A><A NAME="Index920"></A></H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are two basic models in
exception-handling theory. In <I>termination</I> (which is what Java and C++
support), you assume the error is so critical there&#8217;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&#8217;t <I>want</I> to come
back.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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 &#8211; which is how you should set up
situations in Java in which you want resumption-like behavior. (That is,
don&#8217;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><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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 seems it isn&#8217;t quite so useful in practice.
The dominant reason is probably the <A NAME="Index921"></A><I>coupling </I>that
results: your handler must often be aware of where the exception is thrown from
and contain non-generic 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><A NAME="_Toc312374116"></A><A NAME="_Toc375545367"></A><A NAME="_Toc408018594"></A><BR></P></DIV>
<A NAME="Heading287"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
The exception
specification<BR><A NAME="Index922"></A><A NAME="Index923"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In Java, you&#8217;re required 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&#8217;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&#8217;s part of the method
declaration, appearing after the argument list.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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:</FONT><BR></P></DIV>

<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>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you say</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>void</font> f() { <font color=#009900>// ...</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">it means that no exceptions are
thrown from the method. (<I>Except </I>for the exceptions of type
<B>RuntimeException</B>, which can reasonably be thrown anywhere &#8211; this
will be described later.)</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can&#8217;t lie about an
exception specification &#8211; if your method causes exceptions and
doesn&#8217;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 exception correctness can be ensured
<I>at compile time</I>.</FONT><A NAME="fnB39" HREF="#fn39">[39]</A><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There is one place you can lie: you
can claim to throw an exception that you don&#8217;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.</FONT><A NAME="_Toc312374118"></A><A NAME="_Toc375545368"></A><A NAME="_Toc408018595"></A><BR></P></DIV>
<A NAME="Heading288"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Catching any exception<BR><A NAME="Index924"></A><A NAME="Index925"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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&#8217;s pertinent to virtually all programming
activities):</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>catch</font>(Exception e) {
  System.out.println(<font color=#004488>"caught an exception"</font>);
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This will catch any exception, so
if you use it you&#8217;ll want to put it at the <I>end</I> of your list of
handlers to avoid pre-empting any exception handlers that might otherwise follow
it.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Since the <B>Exception</B> class is
the base of all the exception classes that are important to the programmer, you
don&#8217;t get much specific information about the exception, but you can call
the methods that come from <I>its</I> base type
<A NAME="Index926"></A><A NAME="Index927"></A><B>Throwable</B>:</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>String
getMessage(&#160;)</B></FONT><BR><FONT FACE="Georgia">Gets the detail
message. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>String
toString(&#160;)</B></FONT><BR><FONT FACE="Georgia">Returns a short
description of the Throwable, including the detail message if there is
one.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>void
<A NAME="Index928"></A>printStackTrace(&#160;)
</B></FONT><BR><FONT FACE="Georgia"><B>void printStackTrace(PrintStream)
</B></FONT><BR><FONT FACE="Georgia">Prints the Throwable and the
Throwable&#8217;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.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first version prints to
standard error, the second prints to a stream of your choice. If you&#8217;re
working under Windows, you can&#8217;t redirect standard error so you might want
to use the second version and send the results to <B>System.out</B>; that way
the output can be redirected any way you want.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In addition, you get some other
methods from <B>Throwable</B>&#8217;s base type <B>Object</B> (everybody&#8217;s
base type). The one that might come in handy for exceptions is
<A NAME="Index929"></A><A NAME="Index930"></A><B>getClass(&#160;)</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(&#160;)</B> or
<B>toString(&#160;)</B>. You can also do more sophisticated things with
<B>Class</B> objects that aren&#8217;t necessary in exception handling.
<B>Class</B> objects will be studied later in the book.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s an example that shows
the use of the <B>Exception</B> methods: </FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: ExceptionMethods.java</font>
<font color=#009900>// Demonstrating the Exception Methods</font>
<font color=#0000ff>package</font> c09;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> ExceptionMethods {
  <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>"Here's my Exception"</font>);
    } <font color=#0000ff>catch</font>(Exception e) {
      System.out.println(<font color=#004488>"Caught Exception"</font>);
      System.out.println(
        <font color=#004488>"e.getMessage(): "</font> + e.getMessage());
      System.out.println(
        <font color=#004488>"e.toString(): "</font> + e.toString());
      System.out.println(<font color=#004488>"e.printStackTrace():"</font>);
      e.printStackTrace();
    }
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output for this program
is:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Caught Exception
e.getMessage(): Here's my Exception
e.toString(): java.lang.Exception: Here's my Exception
e.printStackTrace():
java.lang.Exception: Here's my Exception
        at ExceptionMethods.main</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see that the methods
provide successively more information &#8211; each is effectively a superset of

⌨️ 快捷键说明

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