Wednesday, December 10, 2008

Handling Exceptions

Handling Exceptions

This chapter is about what happens when Java encounters an error situation that it can't deal with. Over the years, computer programming languages have devised many different ways to deal with these types of errors. The earliest programming languages dealt with them rudely, by abruptly terminating the program and printing out the entire contents of the computer's memory in hexadecimal. This output was called a dump.

Later programming languages tried various ways to keep the program running when serious errors occurred. In some languages, the statements that could potentially cause an error had extra elements added to them that would provide feedback about errors. For example, a statement that read data from a disk file might return an error code if an I/O error occurred. Still other languages let you create a special error processing section of the program, to which control would be transferred if an error occurred.

Being an object-oriented programming language, Java handles errors by using special exception objects that are created when an error occurs. In addition, Java has a special statement called the try statement that you must use to deal with exception objects. In this chapter, you find all the gory details of working with exception objects and try statements.

Understanding Exceptions

An exception is an object that's created when an error occurs in a Java program and Java can't automatically fix the error. The exception object contains information about the type of error that occurred. However, the most important information-the cause of the error-is indicated by the name of the exception class used to create the exception. You don't usually have to do anything with an exception object other than figure out which one you have.

Each type of exception that can occur is represented by a different exception class. For example, here are some typical exceptions:

  • IllegalArgumentException: You passed an incorrect argument to a method.

  • InputMismatchException: The console input doesn't match the data type expected by a method of the Scanner class.

  • ArithmeticException: You tried an illegal type of arithmetic operation, such as dividing an integer by zero.

  • IOException: A method that performs I/O encountered an unrecoverable I/O error.

  • ClassNotFoundException: A necessary class couldn't be found.

There are many other types of exceptions besides these. You find out about many of them in later chapters of this book.

You need to know a few other things about exceptions:

  • When an error occurs and an exception object is created, Java is said to have thrown an exception. Java has a pretty good throwing arm, so the exception is always thrown right back to the statement that caused it to be created.

  • The statement that caused the exception can catch the exception if it wants it. But it doesn't have to catch the exception if it doesn't want it. Instead, it can duck and let someone else catch the exception. That someone else is the statement that called the method that's currently executing.

  • If everyone ducks and the exception is never caught by the program, the program ends abruptly and displays a nasty-looking exception message on the console. (More on that in the next section.)

  • Two basic types of exceptions in Java are checked exceptions and unchecked exceptions:

    • A checked exception is an exception that the compiler requires you to provide for it one way or another. If you don't, your program doesn't compile.

    • An unchecked exception is an exception that you can provide for, but you don't have to.

  • So far in this book, I've avoided using any Java API methods that throw checked exceptions. However, I have used methods that can throw unchecked exceptions. For example, the nextInt method of the Scanner class throws an unchecked exception if the user enters something other than a valid integer value. For more information, read on.

Witnessing an exception

Submitted for your approval is a tale of a hastily written Java program, quickly put together to illustrate certain Java programming details while ignoring others. Out of sight, out of mind, as they say. Said program played a guessing game with the user, accepting numeric input via a class called Scanner.

Yet this same program ignored the very real possibility that the user may enter strange and unexpected data, data that could hardly be considered numeric, at least not in the conventional sense. The time: Now. The place: Here. This program is about to cross over into the Exception Zone.

The program I'm talking about here is, of course, the Guessing Game program that's appeared in several forms in recent chapters. (You can find the most recent version at the very end of Book II, Chapter 7.) This program includes a validation routine that prevents the user from making a guess that's not between 1 and 10. However, that validation routine assumes that the user has entered a valid integer number. If the user enters something other than an integer value, the nextInt method of the Scanner class fails badly.

Figure 8-1 shows an example of what the console looks like if the user enters text (such as five) instead of a number. The first line after the user enters the incorrect data says the program has encountered an exception named InputMismatchException. In short, this exception means that the data entered by the user couldn't be properly matched with the type of data that was expected by the Scanner class. That's because the nextInt method expected to find an integer, and instead it found the word five.

Image from book
Figure 8-1: This program has slipped into the Exception Zone.

Finding the culprit

You can find the exact statement in your program that caused the exception to occur by examining the lines that are displayed right after the line that indicates which exception was encountered. These lines, called the stack trace, list the different methods that the exception passed through before your program was completely aborted. Usually the first method listed is deep in the bowels of the Java API, and the last method listed is your application's main method. Somewhere in the middle, you find the switch from methods in the Java API to a method in your program. That's usually where you find the statement in your program that caused the error.

In Figure 8-1, the stack trace lines look like this:

at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at GuessingGameMethod3.getGuess(GuessingGameMethod3.java:51)
at GuessingGameMethod3.playARound(GuessingGameMethod3.java:31)
at GuessingGameMethod3.main(GuessingGameMethod3.java:13)

Each line lists not only a class and method name, but also the name of the source file that contains the class and the line number where the exception occurred. Thus the first line in this stack trace indicates that the exception is handled in the throwFor method of the Scanner class at line 819 of the Scanner.java file. The next three lines also indicate methods in the Scanner class. The first line to mention the GuessingGame class (GuessingGameMethod3) is the fifth line. It shows that the exception happened at line 51 in the GuessingGameMethod3.java file. Sure enough, that's the line that calls the nextInt method of the Scanner class to get input from the user.

No comments:

Post a Comment