最终嵌套在Exceptions中的行为

时间:2011-01-12 02:47:01

标签: java

今天在工作中,我不得不查看一个类似于这个模拟示例的代码片段。

package test;

import java.io.IOException;
import org.apache.log4j.Logger;

public class ExceptionTester {

    public static Logger logger = Logger.getLogger(ExceptionTester.class);

public void test() throws IOException {
    new IOException();
}

public static void main(String[] args) {
    ExceptionTester comparator = new ExceptionTester();
    try {
        try {
            comparator.test();
        } finally {
            System.out.println("Finally 1");
        }
    } catch(IOException ex) {
        logger.error("Exception happened" ex);
            // also close opened resources
    } 
    System.out.println("Exiting out of the program");
}

import java.io.IOException; import org.apache.log4j.Logger; public class ExceptionTester { public static Logger logger = Logger.getLogger(ExceptionTester.class); public void test() throws IOException { new IOException(); } public static void main(String[] args) { ExceptionTester comparator = new ExceptionTester(); try { try { comparator.test(); } finally { System.out.println("Finally 1"); } } catch(IOException ex) { logger.error("Exception happened" ex); // also close opened resources } System.out.println("Exiting out of the program"); }

它正在打印以下输出。由于内部} 没有try块,我预计编译错误。

Finally 1
Exiting out of the program

我不明白为什么catchIOException块抓住了。如果有人能解释这一点,我将不胜感激,特别是通过引用堆栈展开过程

3 个答案:

答案 0 :(得分:6)

finally块表示必须在正常和异常条件下完成的任务。

示例:你带一个面试候选人去吃午餐。在午餐时,你发现他被警方通缉谋杀。例外!午餐结束了,面试完全失去了,但是......你仍然需要支付午餐费用。

try {
    meetForLunch(interviewCandidate);
}
finally {
    lunchBill.pay();
}

请注意,支付午餐并没有照顾到例外情况,你仍然需要在面试时对凶手采取行动。在处理损伤控制之前,这只是一个松散的结束。

大多数finally块都以这种方式使用:无论是否成功保存数据,都需要关闭文件,无论交易是否被批准,都需要关闭数据库连接等。

并且异常继续以其快乐的方式向外扩展,在封闭范围内寻找匹配的捕获块。

请注意,finally块将始终运行,除非过程在try块仍在执行时结束。

答案 1 :(得分:0)

我认为问题在于你的功能

public void test() throws IOException {
    new IOException();
}

实际上不会抛出异常 - 它只是创建一个新的IOException()对象。将此更改为

public void test() throws IOException {
    throw new IOException();
}

应该解决这个问题。

答案 2 :(得分:0)

上面的代码不需要太多的解释 - 不一定涉及调用堆栈!你有什么困惑?我错过了什么吗? 这是我的解释

第一点

  • 你不需要捕获和捕获 终于阻止了。你可以有一个 他们或他们俩都有 试试块,但不是没有。
  • finally子句中的代码 将永远执行,即使是 异常是从内部引发的 尝试或抓住阻止。如果您的代码有 try或者中的return语句 catch块,里面的代码 finally-block将被执行 在从方法返回之前。

所以在上面的代码中,从未抛出异常(因为你没有在throw方法中使用test()) 但是,finally块已按照语言规范的承诺执行,并且您获得了输出Finally 1。执行序列中的下一个语句是System.out.println("Exiting out of the program");,因为没有IOExceptions,因此catch块永远不会到达。因此,会打印Exiting out of the program