当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Behavior of nested finally in Exceptions

问题描述:

Today at work, I had to review a code snippet that looks similar to this mock example.

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");

}

}

It's printing the following output.I expected an compile error since the inner try did not have a catch block.

Finally 1

Exiting out of the program

I do not understand why IOException is caught by the outer catch block. I would appreciate if anyone can explain this, especially by citing stack unwinding process

网友答案:

A finally block represents a task that has to be done under both normal and abnormal conditions.

Example: You take an interview candidate to lunch. While at lunch, you find out he's wanted by the police for murder. Exception! Lunch is over, the interview is a total loss, but... you still have to pay for lunch.

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

Note that paying for lunch hasn't taken care of the exception, you've still got to do something about the murderer at your interview. It's just a loose end that has to be taken care of before processing with damage control.

Most finally blocks are used in that way: A file needs to be closed whether you successfully saved the data or not, a database connection needs to be closed whether the transaction was approved or not, etc.

And the exception continues outward on its merry way, looking for a matching catch block in an enclosing scope.

Note that finally blocks will always run unless the process ends while the try block is still executing.

网友答案:

I think the problem is that your function

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

Doesn't actually throw an exception - it just creates a new IOException() object. Changing this to

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

should fix this.

网友答案:

The code above does not require much of an explanation - not definitely involving call stacks!. What is your confusion?did I miss something? Here is my explanation

First point

  • You don't need both a catch and a finally block. You can have one of them or both of them with a try-block, but not none of them.
  • The code inside the finally clause will always be executed, even if an exception is thrown from within the try or catch block. If your code has a return statement inside the try or catch block, the code inside the finally-block will get executed before returning from the method.

So in the above code, an exception was never thrown (because you are not using throw in the test() method) However, finally block got executed as promised by the the language spec and you got the output Finally 1. The next statement in the sequence of execution is the System.out.println("Exiting out of the program"); as the catch block never reached as there are no IOExceptions. So, Exiting out of the program is printed.

分享给朋友:
您可能感兴趣的文章:
随机阅读: