10.2 More on Exceptions

More Exceptions

We have covered Java exceptions in several places in the notes, but this section will collate some of the issues and discuss exceptions in some more detail. As you are aware exceptions are "problems" that occur at run-time, during a program's execution. In completing the exercises in the notes you will probably have suffered NullPointerException and/or ArrayIndexOutOfBoundsException exceptions.

These exceptions indicate that there is something wrong with the code that you have written, with the error only apparent at run-time. However, there is a lot more to exceptions in Java than just these errors; the use of exceptions allow us to write robust code that is easier to follow. Not only that, but for the user trying to understand what went wrong with a program, a message such as "USB key is not present" is much more helpful than a message "system error".

Here is an exception code example:

String s = new String("12345");
	int x = (new Integer(s)).intValue();
	System.out.println("We have succeeded.");
	x = x*x;
	System.out.println("The number squared is " + x);
catch(NumberFormatException e)
	System.out.println("Invalid string for conversion to int.");
	System.out.println("We get here always!");

This section of code can catch exceptions using a combination of trycatch and finally blocks of code. In this section of code these blocks of code are called as follows:

  • try - Identifies that an exception may occur in the following block of code.

  • catch - Provides a block of code that can handle a particular type of exception, in this case a NumberFormatException. It is usual to provide some sort of error handling here, for example using a default value, re-prompting the user for a value etc. We just output a message in this example. The NumberFormatException object e can contain further information about the error that occurred. If a single block of code can throw several exceptions, there can be multiple catch blocks. Importantly, the most specific exception must be caught first and the most general caught last (e.g. Exception, which is the parent of all exceptions).

  • finally - A block of code that guarantees to execute, whether the exception occurs or not. This can be used to clean up - for example, closing files, recovering resources etc. In this example case we just display a message.

If we examine this block of code when everything goes correctly, such as when the string is 12345 we get the output:

We have succeeded.
The number squared is 152399025
We get here always!

Importantly, notice that we have displayed the "succeeded" message and that we have squared the value. The finally block is also called.

But if the string is abcde then an exception will occur when we try to turn "abcde" into an Integer through the use of the constructor. We will then get the output:

Invalid string for conversion to int.
We get here always!

Notice this time that we do not get the message "We have succeeded" or do we attempt to convert the code. The execution point has jumped immediately from the construction of the Integer using new Integer(s) to the catch block of code, where we display the "Invalid string for conversion to int" message.

How do we know that the constructor to Integer that accepts a String can throw such an exception? Well it is described in the Java API documentation, where it states that public Integer(String s)throws NumberFormatException . Alternatively, if we were to try and write this code without the try block then the compiler would inform us that we have an unhandled exception as the Java language is quite strict about enforcing exception rules.

Exceptions are very useful in that they improve the legibility of our code and allow us to recover from potentially fatal errors.