Handling Errors Using Exceptions |
The previous sections describe how to construct thetry
,catch
, andfinally
code blocks for thewriteList
example. Now, let's walk through the code and investigate what happens during three scenarios.When all of the components are put together, the
writeList
method looks like this:Thispublic void writeList() { PrintStream pStr = null; try { int i; System.out.println("Entering try statement"); pStr = new PrintStream( new BufferedOutputStream( new FileOutputStream("OutFile.txt"))); for (i = 0; i < size; i++) pStr.println("Value at: " + i + " = " + victor.elementAt(i)); } catch (ArrayIndexOutOfBoundsException e) { System.err.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage()); } catch (IOException e) { System.err.println("Caught IOException: " + e.getMessage()); } finally { if (pStr != null) { System.out.println("Closing PrintStream"); pStr.close(); } else { System.out.println("PrintStream not open"); } } }try
block in this method has three different exit possibilities:This section investigates in detail what happens in the
- The
new FileOutputStream
statement fails and throws anIOException
.- The
victor.elementAt(i)
statement fails and throws anArrayIndexOutOfBoundsException
.- Everything succeeds and the
try
statement exits normally.writeList
method during each of those exit possibilities.Scenario 1: An
IOException
OccursThenew FileOutputStream("OutFile.txt")
statement can fail for any number of reasons: the user doesn't have write permission on the file or directory, the file system is full, or the directory for the file doesn't exist. If any of these situations is true, then the constructor forFileOutputStream
throws anIOException
.When the
IOException
is thrown, the runtime system immediately stops execution of thetry
block. Then the runtime system attempts to locate an exception handler appropriate for handling anIOException
.The runtime system begins its search at the top of the method call stack. When the exception occurred, the
FileOutputStream
constructor was at the top of the call stack. However, theFileOutputStream
constructor doesn't have an appropriate exception handler so the runtime system checks the next method in the method call stack--thewriteList
method. ThewriteList
method has two exception handlers: one forArrayIndexOutofBoundsException
and one forIOException
.The runtime system checks
writeList
's handlers in the order that they appear following thetry
statement. The argument to the first exception handler isArrayIndexOutofBoundsException
, but the exception that was thrown is anIOException
. AnIOException
cannot legally be assigned to anArrayIndexOutofBoundsException
, so the runtime system continues its search for an appropriate exception handler.The argument to
writeList
's second exception handler is anIOException
. The exception thrown by theFileOutputStream
constructor is also anIOException
and can be legally assigned to the handler'sIOException
argument. Thus, this handler is deemed appropriate and the runtime system executes this handler, which prints this statement:Caught IOException: OutFile.txtAfter the exception handler has run, the runtime system passes control to the
finally
block. In this particular scenario, thePrintStream
never was opened, and thuspStr
is null and won't get closed. After thefinally
block has completed executing, the program continues with the first statement after thefinally
block.The complete output that you see from the
ListOfNumbers
program when anIOException
is thrown is this:Entering try statement Caught IOException: OutFile.txt PrintStream not openScenario 2: An
ArrayIndexOutofBoundsException
OccursThis scenario is the same as the first except that a different error occurs during thetry
block. In this scenario, the argument passed to theVector
'selementAt
method is out of bounds. That is, the argument is either less than 0 or is larger than the size of the array. (The way the code is written, this is actually impossible, but let's suppose a bug is introduced into the code when someone modifies it.)As in to scenario 1, when the exception occurs the runtime system stops execution of the
try
block and attempts to locate an exception handler suitable for anArrayIndexOutofBoundsException
. The runtime system searches for an appropriate exception handler as it did before. It comes upon thecatch
statement in thewriteList
method that handles exceptions of the typeArrayIndexOutofBoundsException
. Since the type of the thrown exception matches the type of the exception handler, the runtime system executes this exception handler.After the exception handler has run, the runtime system passes control to the
finally
block. In this particular scenario, thePrintStream
did get opened, thus thefinally
statement closes it. After thefinally
block has completed executing, the program continues with the first statement after thefinally
block.The complete output that you see from the
ListOfNumbers
program when anArrayIndexOutofBoundsException
is thrown is something like this:Entering try statement Caught ArrayIndexOutOfBoundsException: 10 >= 10 Closing PrintStreamScenario 3: The
try
block exits normallyIn this scenario, all the statements within the scope of thetry
block execute successfully and throw no exceptions. Execution falls off the end of thetry
block, and then the runtime system passes control to thefinally
block. Since everything was successful, thePrintStream
is open when control reaches thefinally
block, which closes thePrintStream
. Again, after thefinally
block has completed executing, the program continues with the first statement after thefinally
block.Thus, the output that you see from the
ListOfNumbers
program when no exceptions are thrown is:Entering try statement Closing PrintStream
Handling Errors Using Exceptions |