Study guide: Exceptions to the programming rules, Part 2

Brush up on Java terms, learn tips and cautions, review homework assignments, and read Jeff's answers to student questions

Glossary of terms

catch an exception object
The collective acts of locating, calling, and passing an exception object to an exception handler.
cause
An exception object located within another exception object.
checked exceptions
Exceptions that must be dealt with in a program; the compiler checks to ensure the program handles them.
error
A JVM-related failure, such as running out of memory.
exception chaining
The act of wrapping an exception object inside another exception object.
stack trace
A sequence of method-call stack frames (where each stack frame describes an incomplete method call) and related source code information that identify the location of code responsible for throwing an exception object.
throw an exception object
Either the JVM creating/initializing an unchecked exception object or a program/library creating/initializing that object and passing it to the JVM through the throw statement.
unchecked exceptions
Exceptions that the program doesn't need to handle; the compiler doesn't verify unchecked exceptions.

Tips and cautions

These tips and cautions will help you write better programs and save you from agonizing over why the compiler produces error messages.

Tips

  • Not all legacy exception classes contain constructors that take cause arguments. If you need to store a cause in some exception object's Throwable layer, and there is no constructor that takes a cause argument, call that object's inherited initCause(Throwable cause) method. Remember, you can call that method only once. Furthermore, initCause(Throwable cause) throws a java.lang.IllegalArgumentException object if a reference to the calling object passes as an argument via cause. Finally, initCause(Throwable cause) throws a java.lang.IllegalStateException object if a call has already been made to either that method, the Throwable(String message, Throwable cause) constructor, or the Throwable(Throwable cause) constructor.
  • Never create objects from the Exception class because the exception handler can't distinguish between the different kinds of exceptions those objects represent. (Operator instanceof is useless in such situations.) To avoid that problem, always create exception objects from appropriate Exception subclasses (except for RuntimeException). The subclass's name tells you if that class is appropriate. For example, use FileNotFoundException to describe exceptions that arise from not finding files.
  • To deal with failure that occurs inside a constructor, throw an exception object from that constructor. If the exception object is checked, append a throws clause to the constructor signature. For example: class Employee { Employee () throws IOException { /* ... appropriate code ... */ } }. When a constructor throws an exception object, the JVM does not create an object from the constructor's class. Using the previous example, if Employee() throws an IOException object, the JVM does not create an Employee object.

Cautions

  • Do not attempt to throw objects from any class apart from Throwable or a Throwable subclass. Otherwise, the compiler reports an error. The compiler also reports an error when a method attempts to throw a checked exception object but does not list that object's class name in the method's throws clause.
  • The catch keyword must appear immediately after a try block's closing brace character. The compiler reports an error upon encountering anything else ahead of catch.
  • In multiple catch clauses following a try block, if a catch clause that catches exception objects of some superclass exception type (such as IOException) precedes a catch clause that catches exception objects of one of that superclass exception type's subclass exception types (such as FileNotFoundException), the compiler reports an error.
  • The finally keyword must appear immediately after the closing brace character of a preceding try block or catch clause. The compiler reports an error upon encountering anything else ahead of finally.
  • Do not throw exception objects from finally clauses because you risk losing other exception objects.

Homework

Please answer the following questions and work on the following exercises.

  • What is wrong with the article's SortIntegerArray1 source code?
  • Is the following code fragment legal?

    static void a () throws FileNotFoundException
    {
       try
       {
           throw new FileNotFoundException ();
       }
       catch (FileNotFoundException e)
       {
       }
    }
    

    Why or why not? Assume the code fragment is from a program that has an import java.io.FileNotFoundException; directive.

  • Can a try block appear alone in source code?
  • Why should you use multiple catch clauses instead of one all-encompassing catch clause?
  • Does Java allow any class's objects to be thrown?
  • Rewrite TranslatedExceptionDemo2 to eliminate the ee.initCause (e); method call, but produce the same output.
  • Write a program that demonstrates catching an exception object after performing cleanup tasks. Choose appropriate cleanup tasks for that program.

Answers to last month's homework

  • In last month's excdemo C++ source code and ExcDemo Java source code, why did I not combine, in the same try block, the code that pops integer values from the stack with the code that pushes integer values onto the stack?

    Answer: When an exception object is thrown from a try block, execution leaves that block and an exception handler executes. Once that exception handler completes, the try block's execution does not resume. Therefore, if I were to combine the "push" code with the "pop" code in the same try block, execution would leave the try block after the push-related exception. Because execution would not return to the try block, you would not have a chance to see the pop-related exception -- because the code that pops integers from the stack would never execute.

Related: