📄 chapter09.html
字号:
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="Index943"></A><A NAME="Index944"></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. </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>//: 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.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output is:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>java.lang.RuntimeException: From f()
at NeverCaught.f(NeverCaught.java:9)
at NeverCaught.g(NeverCaught.java:12)
at NeverCaught.main(NeverCaught.java:15)</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">So the answer is: If a
RuntimeException gets all the way out to <B>main( )</B> without being
caught, <B>printStackTrace( )</B> is called for that exception as the
program exits.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Keep in mind that it’s
possible to ignore only <B>RuntimeException</B>s in your coding, since all other
handling is carefully enforced by the compiler. The reasoning is that a
<B>RuntimeException</B> represents a programming error:</FONT><BR></P></DIV>
<OL>
<LI><FONT FACE="Georgia"> An error you cannot catch (receiving a null
handle handed to your method by a client programmer, for example)
</FONT><LI><FONT FACE="Georgia"> An error that you, as a programmer,
should have checked for in your code (such as
<B>ArrayIndexOutOfBoundsException</B> where you should have paid attention to
the size of the array).
</FONT></OL><DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see what a
tremendous benefit it is to have exceptions in this case, since they help in the
debugging process.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It’s interesting to notice
that you cannot classify Java exception handling as a single-purpose tool. Yes,
it is designed to handle those pesky run-time errors that will occur because of
forces outside your code’s control, but it’s also essential for
certain types of programming bugs that the compiler cannot
detect.</FONT><A NAME="_Toc375545373"></A><A NAME="_Toc408018599"></A><BR></P></DIV>
<A NAME="Heading292"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Creating your own exceptions</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You’re not stuck using the
Java <A NAME="Index945"></A>exceptions. This is important because you’ll
often need to create your own exceptions to denote a special error that your
library is capable of creating, but which was not foreseen when the Java
hierarchy was created.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To create your own exception class,
you’re forced to inherit from an existing type of exception, preferably
one that is close in meaning to your new exception. Inheriting an exception is
quite simple:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Inheriting.java</font>
<font color=#009900>// Inheriting your own exceptions</font>
<font color=#0000ff>class</font> MyException <font color=#0000ff>extends</font> Exception {
<font color=#0000ff>public</font> MyException() {}
<font color=#0000ff>public</font> MyException(String msg) {
<font color=#0000ff>super</font>(msg);
}
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Inheriting {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> f() <font color=#0000ff>throws</font> MyException {
System.out.println(
<font color=#004488>"Throwing MyException from f()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> MyException();
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> g() <font color=#0000ff>throws</font> MyException {
System.out.println(
<font color=#004488>"Throwing MyException from g()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> MyException(<font color=#004488>"Originated in g()"</font>);
}
<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>(MyException e) {
e.printStackTrace();
}
<font color=#0000ff>try</font> {
g();
} <font color=#0000ff>catch</font>(MyException e) {
e.printStackTrace();
}
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The inheritance occurs in the
creation of the new class:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>class</font> MyException <font color=#0000ff>extends</font> Exception {
<font color=#0000ff>public</font> MyException() {}
<font color=#0000ff>public</font> MyException(String msg) {
<font color=#0000ff>super</font>(msg);
}
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The key phrase here is <B>extends
Exception</B>, which says “it’s everything an <B>Exception</B> is
and more.” The added code is small – the addition of two
constructors that define the way <B>MyException</B> is created. Remember that
the compiler automatically calls the base-class default constructor if you
don’t explicitly call a base-class constructor, as in the
<B>MyException( )</B> default constructor. In the second constructor, the
base-class constructor with a <B>String</B> argument is explicitly invoked by
using the <B>super</B> keyword.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output of the program
is:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Throwing MyException from f()
MyException
at Inheriting.f(Inheriting.java:16)
at Inheriting.main(Inheriting.java:24)
Throwing MyException from g()
MyException: Originated in g()
at Inheriting.g(Inheriting.java:20)
at Inheriting.main(Inheriting.java:29)</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see the absence of the
detail message in the <B>MyException</B> thrown from
<B>f( )</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The process of creating your own
exceptions can be taken further. You can add extra constructors and
members:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Inheriting2.java</font>
<font color=#009900>// Inheriting your own exceptions</font>
<font color=#0000ff>class</font> MyException2 <font color=#0000ff>extends</font> Exception {
<font color=#0000ff>public</font> MyException2() {}
<font color=#0000ff>public</font> MyException2(String msg) {
<font color=#0000ff>super</font>(msg);
}
<font color=#0000ff>public</font> MyException2(String msg, <font color=#0000ff>int</font> x) {
<font color=#0000ff>super</font>(msg);
i = x;
}
<font color=#0000ff>public</font> <font color=#0000ff>int</font> val() { <font color=#0000ff>return</font> i; }
<font color=#0000ff>private</font> <font color=#0000ff>int</font> i;
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Inheriting2 {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> f() <font color=#0000ff>throws</font> MyException2 {
System.out.println(
<font color=#004488>"Throwing MyException2 from f()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> MyException2();
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> g() <font color=#0000ff>throws</font> MyException2 {
System.out.println(
<font color=#004488>"Throwing MyException2 from g()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> MyException2(<font color=#004488>"Originated in g()"</font>);
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> h() <font color=#0000ff>throws</font> MyException2 {
System.out.println(
<font color=#004488>"Throwing MyException2 from h()"</font>);
<font color=#0000ff>throw</font> <font color=#0000ff>new</font> MyException2(
<font color=#004488>"Originated in h()"</font>, 47);
}
<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>(MyException2 e) {
e.printStackTrace();
}
<font color=#0000ff>try</font> {
g();
} <font color=#0000ff>catch</font>(MyException2 e) {
e.printStackTrace();
}
<font color=#0000ff>try</font> {
h();
} <font color=#0000ff>catch</font>(MyException2 e) {
e.printStackTrace();
System.out.println(<font color=#004488>"e.val() = "</font> + e.val());
}
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A data member <B>i</B> has been
added, along with a method that reads that value and an additional constructor
that sets it. The output is:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Throwing MyException2 from f()
MyException2
at Inheriting2.f(Inheriting2.java:22)
at Inheriting2.main(Inheriting2.java:34)
Throwing MyException2 from g()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -