Documentation

The Java™ Tutorials
Hide TOC
Putting It All Together把它们放在一起
Trail: Essential Java Classes
Lesson: Exceptions
Section: Catching and Handling Exceptions

Putting It All Together把它们放在一起

The previous sections described how to construct the try, catch, and finally code blocks for the writeList method in the ListOfNumbers class.前面的部分描述了如何在ListOfNumbers类中为writeList方法构造trycatchfinally代码块。Now, let's walk through the code and investigate what can happen.现在,让我们浏览一下代码并调查可能发生的情况。

When all the components are put together, the writeList method looks like the following.将所有组件放在一起时,writeList方法如下所示。

public void writeList() {
    PrintWriter out = null;

    try {
        System.out.println("Entering" + " try statement");

        out = new PrintWriter(new FileWriter("OutFile.txt"));
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    } catch (IndexOutOfBoundsException e) {
        System.err.println("Caught IndexOutOfBoundsException: "
                           +  e.getMessage());
                                 
    } catch (IOException e) {
        System.err.println("Caught IOException: " +  e.getMessage());
                                 
    } finally {
        if (out != null) {
            System.out.println("Closing PrintWriter");
            out.close();
        } 
        else {
            System.out.println("PrintWriter not open");
        }
    }
}

As mentioned previously, this method's try block has three different exit possibilities; here are two of them.如前所述,此方法的try块有三种不同的退出可能性;这里有两个。

  1. Code in the try statement fails and throws an exception.try语句中的代码失败并引发异常。This could be an IOException caused by the new FileWriter statement or an IndexOutOfBoundsException caused by a wrong index value in the for loop.这可能是由new FileWriter语句引起的IOException,也可能是由for循环中的错误索引值引起的IndexOutOfBoundsException
  2. Everything succeeds and the try statement exits normally.所有操作都成功,try语句正常退出。

Let's look at what happens in the writeList method during these two exit possibilities.让我们看看writeList方法在这两种退出可能性期间发生了什么。

Scenario 1: An Exception Occurs场景1:发生异常

The statement that creates a FileWriter can fail for a number of reasons.创建FileWriter的语句可能会失败,原因有很多。For example, the constructor for the FileWriter throws an IOException if the program cannot create or write to the file indicated.例如,如果程序无法创建或写入指定的文件,FileWriter的构造函数将抛出IOException

When FileWriter throws an IOException, the runtime system immediately stops executing the try block; method calls being executed are not completed.FileWriter抛出IOException时,运行时系统立即停止执行try块;正在执行的方法调用未完成。The runtime system then starts searching at the top of the method call stack for an appropriate exception handler.然后,运行时系统开始在方法调用堆栈的顶部搜索适当的异常处理程序。In this example, when the IOException occurs, the FileWriter constructor is at the top of the call stack.在本例中,当IOException发生时,FileWriter构造函数位于调用堆栈的顶部。However, the FileWriter constructor doesn't have an appropriate exception handler, so the runtime system checks the next method — the writeList method — in the method call stack.但是,FileWriter构造函数没有适当的异常处理程序,因此运行时系统会在方法调用堆栈中检查下一个方法—writeList方法。The writeList method has two exception handlers: one for IOException and one for IndexOutOfBoundsException.writeList方法有两个异常处理程序:一个用于IOException,另一个用于IndexOutOfBoundsException

The runtime system checks writeList's handlers in the order in which they appear after the try statement.运行时系统按照writeList的处理程序在try语句之后出现的顺序检查它们。The argument to the first exception handler is IndexOutOfBoundsException.第一个异常处理程序的参数是IndexOutOfBoundsExceptionThis does not match the type of exception thrown, so the runtime system checks the next exception handler — IOException.这与引发的异常类型不匹配,因此运行时系统检查下一个异常处理程序—IOExceptionThis matches the type of exception that was thrown, so the runtime system ends its search for an appropriate exception handler.这与抛出的异常类型匹配,因此运行时系统结束对适当异常处理程序的搜索。Now that the runtime has found an appropriate handler, the code in that catch block is executed.现在运行库已经找到了一个合适的处理程序,该catch块中的代码就被执行了。

After the exception handler executes, the runtime system passes control to the finally block.执行异常处理程序后,运行时系统将控制权传递给finally块。Code in the finally block executes regardless of the exception caught above it.finally块中的代码将执行,而不考虑上面捕获的异常。In this scenario, the FileWriter was never opened and doesn't need to be closed.在这种情况下,FileWriter从未打开,也不需要关闭。After the finally block finishes executing, the program continues with the first statement after the finally block.finally块完成执行后,程序继续执行finally块后的第一条语句。

Here's the complete output from the ListOfNumbers program that appears when an IOException is thrown.下面是ListOfNumber程序的完整输出,该程序在引发IOException时显示。

Entering try statement
Caught IOException: OutFile.txt
PrintWriter not open

The boldface code in the following listing shows the statements that get executed during this scenario:下表中的粗体代码显示了在此场景中执行的语句:

public void writeList() {
PrintWriter out = null;

    try {
        System.out.println("Entering try statement");
        out = new PrintWriter(new FileWriter("OutFile.txt"));
        for (int i = 0; i < SIZE; i++)
            out.println("Value at: " + i + " = " + list.get(i));
                               
    } catch (IndexOutOfBoundsException e) {
        System.err.println("Caught IndexOutOfBoundsException: "
                           + e.getMessage());
                                 
    } catch (IOException e) {
        System.err.println("Caught IOException: " + e.getMessage());
    } finally {
        if (out != null) {
            System.out.println("Closing PrintWriter");
            out.close();
        } 
else {
            System.out.println("PrintWriter not open");
        }
    }
}

Scenario 2: The try Block Exits Normally场景2:try块正常退出

In this scenario, all the statements within the scope of the try block execute successfully and throw no exceptions.在这种情况下,try块范围内的所有语句都会成功执行,并且不会抛出异常。Execution falls off the end of the try block, and the runtime system passes control to the finally block.执行从try块的末尾开始,运行时系统将控制权传递给finally块。Because everything was successful, the PrintWriter is open when control reaches the finally block, which closes the PrintWriter.因为一切都成功,所以当控件到达finally块时,PrintWriter将打开,从而关闭PrintWriterAgain, after the finally block finishes executing, the program continues with the first statement after the finally block.同样,在finally块完成执行后,程序继续执行finally块后的第一条语句。

Here is the output from the ListOfNumbers program when no exceptions are thrown.下面是ListOfNumber程序在没有引发异常时的输出。

Entering try statement
Closing PrintWriter

The boldface code in the following sample shows the statements that get executed during this scenario.以下示例中的粗体代码显示了在此场景中执行的语句。

public void writeList() {
PrintWriter out = null;
    try {
        System.out.println("Entering try statement");
        out = new PrintWriter(new FileWriter("OutFile.txt"));
        for (int i = 0; i < SIZE; i++)
            out.println("Value at: " + i + " = " + list.get(i));
                  
    } catch (IndexOutOfBoundsException e) {
        System.err.println("Caught IndexOutOfBoundsException: "
                           + e.getMessage());

    } catch (IOException e) {
        System.err.println("Caught IOException: " + e.getMessage());
                                 
    } finally {
        if (out != null) {
            System.out.println("Closing PrintWriter");
            out.close();
        } 
        else {
            System.out.println("PrintWriter not open");
        }
    }
}

Previous page: The try-with-resources Statement
Next page: Specifying the Exceptions Thrown by a Method