|
|
Handling Errors using Exceptions |
When all of the components are put together, thewriteList()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"); } } }tryblock in this method has three different exit possibilities:This page investigates in detail what happens in the
- The
new FileOutputStreamstatement fails and throws an IOException.- The
victor.elementAt(i)statement fails and throws an ArrayIndexOutOfBoundsException.- Everything succeeds and the
trystatement exits normally.writeList()method during each of those exit possibilities.Scenario 1: An IOException Occurs
Thenew 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 for FileOutputStream throws an IOException.When the IOException is thrown, the runtime system immediately stops execution of the
tryblock. Then the runtime system attempts to locate an exception handler appropriate for handling an IOException.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, the FileOutputStream constructor doesn't have an appropriate exception handler so the runtime system checks the next method in the method call stack--the
writeList()method. ThewriteList()method has two exception handlers: one for ArrayIndexOutOfBoundsException and one for IOException.The runtime system checks
writeList's handlers in the order that they appear following thetrystatement. The argument to the first exception handler is ArrayIndexOutOfBoundsException, but the exception that was thrown is an IOException. An IOException cannot legally be assigned to an ArrayIndexOutOfBoundsException, so the runtime system continues its search for an appropriate exception handler.The argument to
writeList()'s second exception handler is an IOException. The exception thrown by the FileOutputStream constructor is also an IOException and can be legally assigned to the handler's IOException 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
finallyblock. In this particular scenario, the PrintStream never was opened, and thuspStris null and won't get closed. After thefinallyblock has completed executing, the program continues with the first statement after thefinallyblock.The complete output that you see from the ListOfNumbers program when an IOException is thrown is this:
Entering try statement Caught IOException: OutFile.txt PrintStream not openScenario 2: An ArrayIndexOutOfBoundsException Occurs
This scenario is the same as the first except that a different error occurs during thetryblock. In this scenario, the argument passed to the Vector'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
tryblock and attempts to locate an exception handler suitable for an ArrayIndexOutOfBoundsException. The runtime system searches for an appropriate exception handler as it did before. It comes upon thecatchstatement in thewriteList()method that handles exceptions of the type ArrayIndexOutOfBoundsException. 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
finallyblock. In this particular scenario, the PrintStream did get opened, thus thefinallystatement closes it. After thefinallyblock has completed executing, the program continues with the first statement after thefinallyblock.The complete output that you see from the ListOfNumbers program when an ArrayIndexOutOfBoundsException is thrown is something like this:
Entering try statement Caught ArrayIndexOutOfBoundsException: 10 >= 10 Closing PrintStreamScenario 3: The try block exits normally
In this scenario, all the statements within the scope of thetryblock execute successfully and throw no exceptions. Execution falls off the end of thetryblock, and then the runtime system passes control to thefinallyblock. Since everything was successful, the PrintStream is open when control reaches thefinallyblock, which closes the PrintStream. Again, after thefinallyblock has completed executing, the program continues with the first statement after thefinallyblock.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 |