Question

Is there any functional difference?

Connection c = null;
try {
  c = getConnection();
  c.doStuff();
} finally {
  if (c!=null) c.close();
}

vs

Connection c = null;
c = getConnection();
c.doStuff();
try {
} finally {
  if (c!=null) c.close();
}

vs

Connection c = null;
try {
  c = getConnection();
} finally {
  if (c!=null) c.close();
}
c.doStuff();

I feel that all of them will do the same thing in all cases

Was it helpful?

Solution

An exception that occurs outside of a try-finally block is by definition an unhandled exception. That being the case, you don't have any guarantees about how the operating system or runtime will deal with it. Chances are good that an exception unwind won't be triggered, your code will simply abort (maybe abend describes it better in this discussion--"abnormal end"), and your finally block will never execute.

The point of try-finally is to guarantee that code cleanup occurs, and occurs in the correct context.

You must be thinking that the code in the finally block is always going to execute no matter what, and that it is going to execute after the entire method finishes, therefore it doesn't matter whether the other code is located inside or outside the try-finally construct, but that is not correct.

So if you want any run-time guarantees of correct behavior your first example is the only correct one.

  • In your first example, you acquire and more importantly use a connection (to a database, one would presume) inside the try block. If an exception occurs within the try block, then the finally block will execute and close your connection.

  • In your second example, your connection is acquired and used completely outside of the try-catch construct. If an exception occurs using the connection, it is likely that the whole context will just be tossed out, your finally block will not execute, and your connection will not be closed.

  • In your third example, finally is going to execute after try, but before any code that comes after the finally block. You will generate an exception trying to use the connection, because the connection has already been explicitly closed.

OTHER TIPS

Craig already addressed the unhandled exception issue, but I wanted to make it clear. I coded up two examples (the last is just bad because you could be working with a broken connection after an exception has occurred, don't do that). Here is a simple example that throws an ArrayIndexOutOfBoundsException:

class TryCatchFinally {
    static int [] array = new int[1];
    public static void main(String [] args) throws Exception {
        if (args[0].startsWith("1")) {
            version1();
        } else if (args[0].startsWith("2")) {
            version2();
        }
    }
    static int version1() {
        int r = 0;
        try {
            System.out.println("In Try.");
            return array[1];
        } catch (Exception e) {
            System.out.println("In Catch.");
        } finally {
            System.out.println("In Finally.");
        }
        System.out.println("In Return.");
        return r;
    }
    static int version2() {
        int r = array[1];
        try {
            System.out.println("In Try.");
        } catch (Exception e) {
            System.out.println("In Catch.");
        } finally {
            System.out.println("In Finally.");
        }
        System.out.println("In Return.");
        return r;
    }
}

And here is the execution:

(TryCatchFinally)$ javac *.java
(TryCatchFinally)$ java TryCatchFinally 1
In Try.
In Catch.
In Finally.
In Return.
(TryCatchFinally)$ java TryCatchFinally 2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at TryCatchFinally.version2(TryCatchFinally.java:24)
    at TryCatchFinally.main(TryCatchFinally.java:7)
(TryCatchFinally)$

As you can see in the first version an exception handler was registered because the exception occurred within the context of a try block. In the second version there was no registered exception handler and the default exception handler was invoked (meaning an uncaught exception).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top