(syllabus and calendar)

Ch. 9. Exception Handling
pp. 333-364

examples-for-week-9.zip

 

Session 9

Exception Handling


Quiz

Let's throw and catch a hot potato of an exception

Exception Handling

An Exception is an abnormal event that is occurs during the execution of a program. If the exception is not handled optimally, it halts execution and causes the program to abort. This week, we learn how to "handle" exceptions, so that execution can continue if we want, and so the user experiences something more graceful than a crash. Ideally, the exception should provide some information for debugging or technical support, or even allow the user to modify the user input and continue the user's workflow.

The Java Virtual Machine (JVM) does provide a default exception handling mechanism, which is to crash. At least the crash is accompanied with an a string representation that includes the name of the exception and the line of code associated with the exception. Often, Java provides default behavior without us having to write code for it. In this case, the result is the same as if we had written a try block and a catch block, with the catch block printing the stack trace. The printStackTrace() method is behavior that every Exception object inherits from Throwable.

What happens if the class with main is in a file whose name does not match the class name? In this case the file name is TestClassNameMismatch.java and the class with main is named Test.

Note that the default stack trace information is printed to System.err - http://download.oracle.com/javase/6/docs/api/java/lang/System.html#err

What happens if we try to do things with an object that does not exist? - http://download.oracle.com/javase/6/docs/api/java/lang/NullPointerException.html
In this case, the crunch method is defined with a formal parameter that expects a runtime argument to be an object of a certain type, that is, an array of type int, but the runtime call fails to provide the expected object.

The compiler will NOT allow us to pass in a runtime object that is an int, a boolean, or a String. However, if we pass in null, the compiler respects that null is possible for an object and allows compilation to proceed. Only at runtime do we see the Exception.

Every exception is an object of a specific type. Java is rigorous in using Object-Oriented technology for exceptions.

To review, the crash is the result of using what we might call the default exception handler, which is the JVM. The JVM handles an exception by

In the following case, at runtime we reference an index in an array of chars that is outside the length of the array. Java arrays are zero-based so the stay within the bounds of the array, the maximum index is the array length minus 1.

Remember that a String is internally implemented by the JVM as an array of type char. If we try to get the character at an index with negative value or the value of the length of the char array, a StringIndexOutOfBoundException is thrown:

If we handle errors using Java's built-in try/catch mechanism, exceptions can occur without necessarily blocking program execution. The program might even be able to recover from the exception. The try block contains whatever might cause a problem. The catch block contains the behavior to execute if and when such a problem occurs. For example, the program might prompt the end-user to enter valid data.

You can create your own custom exception type as a subclass of Exception, or as a subclass of any existing subclass of Exception. Line 15 below uses the keyword "throw" to create an exception object. This custom exception, like all exceptions (except Exception) is a subclass of Exception.

The following example also has two catch blocks. Each catch block is like an overload signature of an overloaded constructor or method. Each catch block must be unique in the type of runtime parameter, that is the Exception subclass, it accepts.


Exception handling is built into the architecture of the Java language. Insofar as every exception is a subclass of java.lang.Exception, exception handling provides a good  example of how the object-oriented paradigm is fundamental to the language.

Sun's tutorial: http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html
   java.lang.Throwable is the superclass for both Error and Exception
In Java terminology, an Error is something beyond the programmer's control and something the programmer should not try to handle.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Error.html
An Exception is a potential problem that your application should consider.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html


The default java.lang package defines both the Exception class and the Error class. When the exception condition occurs, the virtual machine can construct an object of type Exception . This object inherits methods from its superclass, Throwable, that are useful for diagnosis of the problem.

Both Error and Exception inherit from Throwable (that is, they can occur at runtime), and Throwable inherits from Object.
Throwable provides methods that are common to errors and exceptions (re-use code!), such as printStackTrace(), getCause() and toString().

As a programmer, you prepare for the possibility of an exception by writing coded to handle the exception.

Unchecked exceptions

The architects of Java considered some exceptions to be so foreseeable that Java automatically handles them.. A better name might be: "automatically handled exceptions".  Because Java handles these exceptions automatically, the compiler does not check to see whether you handle them in YOUR code:

The following example is for an unchecked exception: divide by zero.

The minimal mechanism to handle Exception objects involves two keywords: try and catch.

Note that e.toString() is possible because every Exception object inherits from the class Throwable.
We can print the exception by passing it as a runtime argument to the println method signature that accepts an object http://download.oracle.com/javase/1.4.2/docs/api/java/io/PrintStream.html#println%28java.lang.Object%29

Catching more than one exception

In the following, each catch clause is defined to handle a different type of runtime Exception object.

The output above occurred because no command-line arguments were given at runtime, which causes a divide-by-zero exception on line 7.

If instead at runtime there are three (3) command-line arguments, the output shows a different exception because line 11 tries to access the 42nd element in an array that only has 3 elements:

The following example has two try blocks, each of which catches a different exception.


Declaring that a method throws exceptions - "checked exceptions"

We have encountered several runtime exceptions:

which are subclasses of RuntimeException. Such exceptions are not checked by the compiler.

The following program does NOT compile because it has a method called throwCustomException that:

The problem at Line 18 occurs because Line 11 does not declare that this method can throw an Exception or a subclass of Exception. That means this program is not exempt from compiler checking the way that RuntimeException or its subclasses are except from compiler checking.

One way to avoid the compiler's refusal is to make the custom exception a subclass of RuntimeException (Line 2).

Another way to keep the compiler happy with a non-runtime exception thrown by a method that does not declare throws, is to have the method that throws the exception also catch the exception (see Line 21 and Line 26).

To conclude, if you write a method that throws an exception that is not a runtime exception, and your method does not catch the exception, then you must declare that your method throws this exception. If another programmer wants to use your method, that programmer can see that your method throws this non-runtime exception. This allows the user of your method to write a catch block external to your method.

The compiler checks to see if you handle or use the keyword throws for the following kinds of exceptions, none of which are a subclass of RuntimeException:

These exceptions are "checked" exceptions because the architects of Java considered that they could write a compiler that could check for them. The unchecked exceptions include problems, such as bad user input at runtime causing a divide by zero, that the compiler cannot check.

This example shows the syntax for declaring that a method "throws" a checked exception. In this case, the throwOne method throws the exception up to the caller, which in this case is the main method.

If your application works with system input and output, the java.io package, it must declare that it throws IOException - http://www.write-technical.com/126581/session10/io/session10.htm#Byte%20array

How would an IOException be caught in the following?:

If you use this method, which can throw the IOException , you can write your own exception handling routine according to your needs (or those of your users).



Call Stack Location of Exception Handling

Some integrated development environments (IDEs) are able to visually represent the call stack, which can help for debugging.

In the following code, the unhandled exception is propagated up the call stack to the caller, which in this case is the main method.
An unhandled exception is always propagated up the call stack until it is handled or reaches its caller.

You might want to follow the call chain associated with an exception to help with debugging code, so the superclass of Exception, Throwable, provides a method for getting the stack trace - http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html#printStackTrace%28%29

Before exception is generated.
java.lang.ArrayIndexOutOfBoundsException: 7
at ExcTest.genException(StackTraceBubble.java:8)
at StackTraceBubble.myMethod(StackTraceBubble.java:18)
at StackTraceBubble.main(StackTraceBubble.java:29)
Before exception is generated.
Standard message is:
java.lang.ArrayIndexOutOfBoundsException: 7

Stack trace:
java.lang.ArrayIndexOutOfBoundsException: 7
at ExcTest.genException(StackTraceBubble.java:8)
at StackTraceBubble.main(StackTraceBubble.java:30)
After catch statement.

You can have a superclass handle a group of exceptions that get thrown up to the superclass from a group of subclasses.
The location of exception handling is flexible in Java.

Here is another example that "throws" an exception (a custom exception), and it has a "finally" block (described in the following section): CallStackExampleWithCustomException3.java

Cleaning up with finally

The finally block executes whether or not an exception is thrown in the try block.

Use case for finally: you might want a method to do some cleanup, such as close a database connection or a file buffer, whether or not an exception occurs.


Defining your own exceptions

Why define your own exceptions? Because it allows your program to be aware of a certain situation that the standard Java APIs cannot know about.

String[] buzzwords = {"replace", "excellent", "resonate", "create", "renounce"};
try
{
    for(String x : buzzwords)
    {
        System.out.println(x);
        if (x == "resonate")
        {
            throw new MyBuzzwordException();
        }
    }
}

Your custom exception might notice that the user is trying to  set the same string for both username and password, then take appropriate action, such as notifying the user that the password must be set to a different string.

Because Exception is an exposed class, you can subclass it (customize it) for your needs. Java provides specific Exceptions for the core APIs, but only domain programmers know which domain objects and Exceptions they need.


Exception Handling summary

To review, all Exceptions are a subclass of Throwable: http://java.sun.com/j2se/1.4.1/docs/api/java/lang/Throwable.html

This allows for code re-use and default behavior. If Throwablewere an interface, Exceptions would not inherit default behavior, such as GetStackTrace
   http://java.sun.com/j2se/1.4.1/docs/api/java/lang/Throwable.html#getStackTrace()
and toString
  http://java.sun.com/j2se/1.4.1/docs/api/java/lang/Throwable.html#toString()

In  Java, objects of type Error are beyond the programmer's control, and Error objects also inherit the default behavior of Throwable.

Some Exceptions are built into Java's API specification. For example, the ArithmeticException occurs if a program tries to divide a number by zero.
   http://java.sun.com/j2se/1.4.1/docs/api/java/lang/ArithmeticException.html

You can have a catch statement for each type of exception.

To ensure that a specialized exception is handled, make its catch block precede the catch block of its superclass. Otherwise, the more general superclass will handle the subclass exceptions, and you lose the ability to ever get to the specialized exception.

The compiler complains:

ExcDemo5.java:20: exception java.lang.ArrayIndexOutOfBoundsException has already been caught
catch (ArrayIndexOutOfBoundsException exc)

You can have inner try blocks for specialized errors, and reserve the outmost try block for the error handling to use if all the previous attempts fail.

To create your custom exception class, you extend Java's Exception class. As always, you need to create an exception object, and your catch block must provide a reference to the exception object.

Another example:

The following program reads from a file by using the read method of the Java io package. The first line of the program is the import statement that gives this application access to all the members of the io package. Which two exceptions does the following program handle?

If I give a file name as a command-line argument, the program prints to the screen the contents of the file:


Review of Exceptions

An exception is a non-normal condition that your code handles in a catch block. A finally block is for clean-up code that you want to happen at the end of method execution whether or not an Exception is thrown. Generally speaking, an exception can be thrown during execution of a try block. The finally block executes after execution leaves the try block, whether the cause of executing leaving the try block is no Exception was thrown and all the try block code has completed it execution, or an Exception was thrown and execution immediately left the try block.

Throws keyword: Checked and Unchecked Exceptions

Checked exceptions are certain Exceptions that that the compiler expects you, as programmer, to catch. These include input/output exceptions (IO Exception), NoSuchMethodException, ClassNotFoundException, and others listed in Table 9-3 (p. 355) of the textbook. If the method you defined MIGHT throw one of the checked exceptions AND the method does not have a catch block for that exception, then the method must declare that is capable of throwing the exception:

void myMethod() throws NoSuchMethodException { ... }

This tells the Java Virtual Machine that if NoSuchMethodException is thrown during the execution of myMethod(), then the JVM should look for a catch block in the method that calls myMethod(), which might be main().

On the other hand, unchecked Exceptions are something that the compiler does not care about. For example, it is your choice whether to have a catch block for ArithmeticException [for divide by zero], ArrayIndexOutOfBoundsException [reference to an element beyond the length of the array], NegativeArraySizeException [setting the length to less than zero]. The compiler does not force you to handle these exceptions. If you do not write a catch block for the unchecked Exceptions, the JVM will automatically return the Exception message as the application fails (crashes). Other unchecked exceptions are listed in Table 9-2 (p.354).

Output is:

size = 3
length is: 3
size = 2
length is: 2
size = 1
length is: 1
size = 0
length is: 0
size = -1
ThomasException has been thrown.
ThomasException is ThomasException
Stack trace next
ThomasException
at DemoThomasExceptionSpecial.main(DemoThomasExceptionSpecial.java:25)
size = -2
Negative array java.lang.NegativeArraySizeException
Stack trace next
java.lang.NegativeArraySizeException
at DemoThomasExceptionSpecial.main(DemoThomasExceptionSpecial.java:27)


Let's look at how to catch an input/output exception when we want to read from a file.

All exceptions inherit from Throwable, so let's review Throwable

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Throwable.html

public class Throwable
extends Object
implements Serializable

The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause.

Instances of two subclasses, Error and Exception, are conventionally used to indicate that exceptional situations have occurred. Typically, these instances are freshly created in the context of the exceptional situation so as to include relevant information (such as stack trace data).

===============

Throwable provides two methods I want to point out:

getMessage

public String getMessage()
// returns the detail message string of this Throwable instance (which may be null).

toString

public String toString()
Returns a short description of this throwable. If this Throwable object was created with a non-null detail message string, then the result is the concatenation of three strings:

If this Throwable object was created with a null detail message string, then the name of the actual class of this object is returned.

===============

Let's look at Error

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Error.html

public class Error
extends Throwable

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.

===============

Let's look at Exception

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html

public class Exception
extends Throwable

The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.

 ===============

 System.out.println(" The exception message is " + e.getMessage() + " and the exception string is " + e.toString());
===============

  1. What causes the ArrayIndexOutOfBounds exception?
  2. Is Throwable a class or an interface? What is the advantage of having it be the way it is?
  3. What is the difference between an Error and an Exception?

Stack Trace

When an exception occurs, the JVM normally prints out a stack trace. A stack trace can help you debug your code. It indicates what happened before the exception occurred. It can be useful for debugging because it indicates the series of method calls, and even specific lines of execution, the precede the exception being thrown.


Possible Logic for try block with throw

try
  {
     if (coverage2.equals("liability"))
  {
  liabilityFlag = true;
  liabilityPremium = premium2;
  }
  else if (coverage2.equals("physicalDamage"))
  {
    physicalDamageFlag = true;
    physicalDamagePremium = premium2;
  }
  else
    throw
new CoverageException (coverage2);
  }
  catch (CoverageException e)
  {
    System.out.println("EXCEPTION is " + e.toString());
  }



Quiz - Session 9

  1. What causes the ArrayIndexOutOfBounds exception?

  2. Is Throwable a class or an interface? What is the advantage of having it be the way it is?

  3. If you try to divide by zero, will you get an Error or an Exception, and what is its name?

  4. What makes execution skip over the catch block?

  5. What makes execute skip over part of the try block?

  6. What is the difference between an Exception and an Error?

  7. When do you use the keyword throw?

  8. What does the finally code block do if there is an exception? What does the finally code block do if there is no exception?

  9. What is a use case for a finally block?

  10. If there are multiple catch blocks, must each one have a unique signature in terms of exception type?

  11. We saw how inheritance is enforced by a subclass implicitly calling the constructor of its superclass. Should we write our code so that superclass version of the exception is caught first?