views:

490

answers:

8

What's the difference between

try {
    fooBar();
} finally {
    barFoo();
}

and

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

I like the second version better because it gives me access to the Throwable. Is there any logical difference or a preferred convention between the two variations?

Also, is there a way to access the exception from the finally clause?

+27  A: 

These are two different things:

  • The catch block is only executed if an exception is thrown in the try block.
  • The finally block is executed always after the try(-catch) block, if an exception is thrown or not.

In your example you haven't shown the third possible construct:

try {
    // try to execute this statements...
}
catch( SpecificException e ) {
    // if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
    // if a more general exception was thrown, handle it here
}
finally {
    // here you can clean things up afterwards
}

And, like @codeca says in his comment, there is no way to access the exception inside the finally block, because the finally block is executed even if there is no exception.

Of course you could declare a variable that holds the exception outside of your block and assign a value inside the catch block. Afterwards you can access this variable inside your finally block.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    trowable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
tangens
A corollary to that is that you *can't* access the `Throwable` from the `finally` block, because there might not *be* a `Throwable`.
Dean Harding
+1  A: 

try is used to run a method that may throw an exception

catch is used to "catch" stop that exception

finally is used for any clean up needed from that exception being caught or not

Kieran
+4  A: 

These are not variations, they're fundamentally different things. finally is executed always, catch only when an exception occurs.

Michiel Buddingh'
A: 

Finally block is always executed. Catch block is executed only when an exception that matches the blocks parameter is catched.

mkorpela
+2  A: 
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. All try statements must include either one catch clause or a finally clause
  2. It can have a multiple catch clauses but only one finally clause
  3. During any execution, if any errors occurs, then the Control is transferred to the appropriate Catch block and executes the statements and Finally block is executed.

No Matter what The Finally block is always executed, So in General, Finally block is used, when you have sessions, Database connections or Files or sockets are open, then the code for closing those connections will be placed. This is just to make sure in an application no memory leaks or Any other issues should not occur.

harigm
+1  A: 

Finally and catch blocks are quite different:

  • Within the catch block you can respond to the thrown exception. This block is executed only if there is an unhandled exception and the type matches the one or is subclass of the one specified in the catch blocks parameter.
  • Finaly will be allway executed after try and catch blocks whether there is an exception raised or not.

So

try {
  //some code
}
catch (ExceptionA) {
  //only gets executed if ExceptionA was thrown in try block
}
catch (ExceptionB) {
  //only gets executed if ExceptionB was thrown in try block
}

differs from

try {
  //some code
}
finally {
  //gets executed whether or not an exeption was thrown in try block
}

signifficantly.

If you define a try block you have to define

  1. one try block or
  2. one or more catch blocks or
  3. one or more catch blocks and one try block

So the following code would be valid too:

try {
  //some code
}
catch (ExceptionA) {
  //only gets executed if ExceptionA was thrown in try block
}
catch (ExceptionB) {
  //only gets executed if ExceptionB was thrown in try block
}
//even more catch blocks
finally {
  //gets executed whether or not an exeption was thrown in try block
}
TheMorph
A: 

Is there a way to access the Exception object in the finally block without using the catch block?

vaibhav
+1  A: 

Even in the first form you could log it in the calling method. So there is no big advantage unless you want to do some special handling right there.

fastcodejava