Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

My java code is just like below:

public void check()throws  MissingParamException{
    ......
}
public static void main(){
    PrintWriter out = response.getWriter();
    try {
        check();
    } catch (MissingParamException e) {
        // TODO Auto-generated catch block
        out.println("message:"+e.getMessage());
        e.printStackTrace();
        out.close();
    }finally{
        out.close();
    }
    //out.close();
}

Then, my confusion is: what the difference if I put out.close() in a finally code block or if I just remove finally code block and put out.close() behind catch clause (which has been commented in the code). I know that in both ways, the out.close() will be executed because I know that whether the exception happened, the code behind the catch clause will always be executed.

share|improve this question

4 Answers 4

up vote 8 down vote accepted

The finally {} block is always called (unless you call exit() before finally is reached - but you won't be doing that most of the time).

The purpose of finally is to clean up any resources allocated in the try {} block, even if something was thrown and it hit the catch{} block.

Consider the code:

public class Hello {

    public static void main(String[] args) {
        hello();
    }

    public static void hello() {
        try {
            System.out.println("hi");
            return;
        } catch (RuntimeException e) {
        } finally {
            System.out.println("finally");
        }
    }
}

While there isn't any resource allocation in this, just pretend there is. This will print out:

hi
finally

If you had opened a file in the try block, the finally is the place to clean it up. If you had opened one file, and then tried to open another one (that threw an exception), the finally is the place to clean that up.

If there was an uncaught exception by the catch block, then the finally would run, and the exception would get passed on up.

Putting out.close() in the catch and the finally is redundant - because it will be run in the finally block - on a caught exception or successful completion of the try.

With the existing code, the following code paths are possible:

  • No exception:

    1. check() - no exception thrown
    2. finally { } - out.close
  • Caught exception:

    1. check() - MissingParamException thrown
    2. catch { } - stuff and out.close
    3. finally { } - out.close
  • Uncaught exception:

    1. check() - NPE thrown
    2. finally { } - out.close

You should be able to see from this, the finally is always called, and in the caught exception, out.close() is invoked twice.

The associated spec is §14.20.2 in Java SE 7 language specification.

share|improve this answer

The difference is that if your check() function throws any exception OTHER than MissingParamException, anything below try/catch will not get executed because your function's stack will get unrolled until a catch is found that will handle that exception of that type (or possibly thread exits if exception is not handled). However, the code you put inside the finally clause is guaranteed to be executed no matter what happens inside the try block.

So in your case leaving out.close() inside the finally block would be a more correct thing to do.

share|improve this answer
    
Simple and to the point. –  Disco 3 Oct 18 '13 at 9:50

Let's do the case analysis.

  1. No exception thrown: No difference
  2. MissingParamException thrown: No difference
  3. Some exception you don't have a catch for i. e. Null Ref: If it is in the finally out.close() will be called. If it is after everything then it will not be called.

    Incidentally you call close in the catch block and the finally block that means when a MissingParamException is thrown you call close twice. Not a big deal, just not necessary.

share|improve this answer

Most has been answered in the other answers but one thing not: If you choose to not use finally and your code goes into you catch block and there's another exception in your catch block then no close will be called at all.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.