放在一起
前面的部分描述了如何为ListOfNumbers
类中的writeList
方法构造try
,catch
和finally
代码块。现在,让我们遍历代码并研究可能发生的情况。
当所有组件放在一起时,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");
}
}
}
如前所述,此方法的try
块具有三种不同的退出可能性:这是其中两个。
-
try
语句中的代码失败,并引发异常。这可能是new FileWriter
语句引起的IOException
或for
循环中的错误索引值导致的IndexOutOfBoundsException
。 -
一切成功,并且
try
语句正常退出。
让我们看看在这两种退出可能性期间writeList
方法中发生了什么。
情况 1:发生异常
创建FileWriter
的语句可能由于多种原因而失败。例如,如果程序无法创建或写入指示的文件,则FileWriter
的构造函数将引发IOException
。
当FileWriter
抛出IOException
时,运行时系统立即停止执行try
块;正在执行的方法调用未完成。然后,运行时系统开始在方法调用堆栈的顶部搜索适当的异常处理程序。在此示例中,当发生IOException
时,FileWriter
构造函数位于调用堆栈的顶部。但是,FileWriter
构造函数没有适当的异常处理程序,因此运行时系统会检查方法调用堆栈中的下一个方法writeList
方法。 writeList
方法具有两个异常处理程序:一个用于IOException
和一个用于IndexOutOfBoundsException
。
运行时系统按照writeList
的处理程序在try
语句之后出现的 Sequences 检查它们。第一个异常处理程序的参数为IndexOutOfBoundsException
。这与引发的异常类型不匹配,因此运行时系统将检查下一个异常处理程序IOException
。这与引发的异常类型匹配,因此运行时系统结束了对适当异常处理程序的搜索。现在,运行时已找到合适的处理程序,该catch
块中的代码将被执行。
异常处理程序执行后,运行时系统将控制权传递给finally
块。 finally
块中的代码将执行,无论其上方catch的异常如何。在这种情况下FileWriter
从未打开过,也不需要关闭。 finally
块完成执行后,程序 continuefinally
块之后的第一条语句。
这是引发IOException
时出现的ListOfNumbers
程序的完整输出。
Entering try statement
Caught IOException: OutFile.txt
PrintWriter not open
以下清单中的粗体代码显示了在这种情况下执行的语句:
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");
}
}
}
情况 2:try 块正常退出
在这种情况下,try
块范围内的所有语句都将成功执行,并且不会引发任何异常。执行从try
块的末尾开始,运行时系统将控制权传递给finally
块。因为一切都成功,所以当控制到达finally
块时,PrintWriter
打开,该块关闭PrintWriter
。同样,在finally
块完成执行之后,程序将 continuefinally
块之后的第一条语句。
这是未引发任何异常时ListOfNumbers
程序的输出。
Entering try statement
Closing PrintWriter
以下示例中的粗体代码显示了在这种情况下执行的语句。
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");
}
}
}