Standard Java exceptions

Bruce Eckel’s Thinking in Java Contents | Prev | Next

Java
contains a class called
Throwable
that describes anything that can be thrown as an exception. There are two
general types of
Throwable
objects (“types of” = “inherited from”). Error
represents compile-time and system errors that you don’t worry about
catching (except in special cases).
Exception
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.

The
best way to get an overview of the exceptions is to browse online Java
documentation from
http://java.sun.com.
(Of course, it’s easier to download it first.) 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.

java.lang.Exception

The
special case of RuntimeException

The
first example in this chapter was

if(t
== null)


throw new NullPointerException();

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
RuntimeException,
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
RuntimeException,
since that’s just assumed. Because they indicate bugs, you virtually
never catch a
RuntimeException
– it’s dealt with automatically. If you were forced to check for
RuntimeExceptions
your code could get messy. Even though you don’t typically catch
RuntimeExceptions,
in
your own packages you might choose to throw some of the
RuntimeExceptions.

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
RuntimeException
could percolate all the way out to your
main( )
method
without being caught. To see what happens in this case, try the following
example:

//: NeverCaught.java
// Ignoring RuntimeExceptions
 
public class NeverCaught {
  static void f() {
    throw new RuntimeException("From f()");
  }
  static void g() {
    f();
  }
  public static void main(String[] args) {
    g();
  }
} ///:~ 

You
can already see that a
RuntimeException
(or
anything inherited from it) is a special case, since the compiler doesn’t
require an exception specification for these types.

The
output is:

java.lang.RuntimeException: From f()
        at NeverCaught.f(NeverCaught.java:9)
        at NeverCaught.g(NeverCaught.java:12)
        at NeverCaught.main(NeverCaught.java:15)

So
the answer is: If a RuntimeException gets all the way out to
main( )
without being caught,
printStackTrace( )
is called for that exception as the program exits.

Keep
in mind that it’s possible to ignore only
RuntimeExceptions
in your coding, since all other handling is carefully enforced by the compiler.
The reasoning is that a
RuntimeException
represents a programming error:

  1. An
    error you cannot catch (receiving a null handle handed to your method by a
    client programmer, for example)
  2. An
    error that you, as a programmer, should have checked for in your code (such as
    ArrayIndexOutOfBoundsException
    where you should have paid attention to the size of the array).
You
can see what a tremendous benefit it is to have exceptions in this case, since
they help in the debugging process.

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.

More by Author

Must Read