try catch finally

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

deljaroo
Posts: 6
Joined: Sat Jan 15, 2011 4:40 am UTC

try catch finally

Postby deljaroo » Sat Jan 15, 2011 4:45 am UTC

I am wondering why I would do this:

Code: Select all

try
{
     //codeA
}
catch(Throwable e)
{
     //codeB
}
finally
{
     //codeC
}


When I could just do this instead:

Code: Select all

try
{
     //codeA
}
catch(Throwable e)
{
     //codeB
}
//codeC


thanks guys

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: try catch finally

Postby phlip » Sat Jan 15, 2011 6:17 am UTC

The main difference is that if codeB can itself break out - eg it throws an exception itself, or has a return or break/continue, then with the finally block, then codeC will still run, but without it, it won't. Also, if codeA throws an exception that isn't caught (which can't happen in your example, since you're catching Throwable, but in real code you would never do that, as you don't want to catch Errors).

Basically, your second example will only run codeC if the control either reaches the bottom of the try block or throws an exception which is then caught and then control reaches the bottom of the catch block. Whereas in the first example, the code in the finally block will be run regardless of how the other blocks end (barring something abnormal like exiting the program outright with System.exit(), or killing the process, or a power failure, or similar unusual events).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

0xBADFEED
Posts: 687
Joined: Mon May 05, 2008 2:14 am UTC

Re: try catch finally

Postby 0xBADFEED » Sat Jan 15, 2011 7:43 pm UTC

To echo some of what phlip said you use finally blocks when you want to run some code regardless of whether or not an error occurs. Specifically, code in a finally block is guaranteed to execute no matter how the try block exits. Typically that means you put code that deals with releasing resources in finally blocks. For example:

Code: Select all

MyStream stream  = null;
try {
   stream = new MyStream("SomeFile.data");
   //A bunch of code that might throw exceptions
} catch(MySpecialException e) {
   //handle exception
} finally {
   if(stream != null)
      stream.close()
}

This code correctly releases the stream regardless of whether or not the try block succeeds. Additionally, it closes the stream even if an uncaught exception is thrown out of the try block or the try block explicitly returns. Using a try-finally block together without a catch block can sometimes be even more useful, as you often don't have enough context at the call-site to handle the exception anyway. Example:

Code: Select all

MyStream stream  = null;
try {
   stream = new MyStream("SomeFile.data");
   //A bunch of code that might throw exceptions
} finally {
   if(stream != null)
      stream.close()
}

This form allows any exceptions to propagate up the stack where they may be more appropriately handled but also releases the stream resource.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6598
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: try catch finally

Postby Thesh » Sat Jan 15, 2011 7:57 pm UTC

Also, in C# and I think Java (someone should verify), finally runs even if you have a return statement. Take the following C# program.

Code: Select all

static void Main(string[] args)
{
   try
   {
      Console.WriteLine("Try");
      return;
   }
   finally
   {
      Console.WriteLine("Finally");
   }
}


This will output :

Code: Select all

Try
Finally


This is probably the case with most if not all languages that implement finally, but I can't guarantee it.
Summum ius, summa iniuria.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: try catch finally

Postby Rysto » Sat Jan 15, 2011 8:25 pm UTC

Thesh wrote:Also, in C# and I think Java (someone should verify), finally runs even if you have a return statement.

It's definitely true. I once saw the following code in Java:

Code: Select all

Foo getFoo() {
    try {
        return lookupFoo();
    } finally {
        return null;
    }
}

Didn't quite do what the author was intending. :D

Alexander The 1st
Posts: 44
Joined: Fri Apr 17, 2009 10:47 pm UTC
Contact:

Re: try catch finally

Postby Alexander The 1st » Sun Jan 16, 2011 3:00 am UTC

Rysto wrote:
Thesh wrote:Also, in C# and I think Java (someone should verify), finally runs even if you have a return statement.

It's definitely true. I once saw the following code in Java:

Code: Select all

Foo getFoo() {
try {
return lookupFoo();
} finally {
return null;
}
}

Didn't quite do what the author was intending. :D


Actually, out of curiosity, what did that do? Return lookupFoo() + null?

Also, what was it intending to do? Return null if the try block breaks, but lookupFoo() if it worked?
...YOU DIDN'T SEE ANYTHING...

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6598
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: try catch finally

Postby Thesh » Sun Jan 16, 2011 3:32 am UTC

In C# return is not allowed in the finally, and it won't build. My guess is that if Java did allow it, it would return null no matter what.

EDIT:

http://stackoverflow.com/questions/6503 ... mp-finally

Also, although it's bad practice, if there is a return statement within the finally block, it will trump any other return from the regular block. That is, the following block would return false:

Code: Select all

try { return true; } finally { return false; }

Summum ius, summa iniuria.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: try catch finally

Postby Rysto » Sun Jan 16, 2011 4:33 am UTC

Alexander The 1st wrote:Actually, out of curiosity, what did that do? Return lookupFoo() + null?

It called lookupFoo(), and always returned null.

Also, what was it intending to do?

Return null if lookupFoo() threw an exception.

User avatar
flying sheep
Posts: 63
Joined: Sun Jan 31, 2010 12:35 am UTC

Re: try catch finally

Postby flying sheep » Sun Jan 16, 2011 12:50 pm UTC

i saw some reallyy nice WTFs regarding java and try/catch/finally somewhere…

however, i just came here to say: that this is a special case. and while language developers should keep it simple, it’s really nice to have such elegant solutions at hand

e.g. python has an “else” black for “for” loops, too, which executes when the loop finishes normally (i.e. without flow statements, or with “continue”)
this is great if you need to maually search for some condition to be true in a sequence, and execute code when this is the case. in many other languages, you’ll have to use a boolean variable here.

deljaroo
Posts: 6
Joined: Sat Jan 15, 2011 4:40 am UTC

Re: try catch finally

Postby deljaroo » Mon Jan 17, 2011 6:39 pm UTC

I had no idea it would execute even if it breaks or returns; I think I like that
Thanks

User avatar
HarvesteR
Posts: 65
Joined: Mon May 10, 2010 1:13 pm UTC

Re: try catch finally

Postby HarvesteR » Tue Jan 18, 2011 10:35 pm UTC

flying sheep wrote:e.g. python has an “else” black for “for” loops, too, which executes when the loop finishes normally (i.e. without flow statements, or with “continue”)


Best. Feature. Ever.

All languages should implement that... Python spoils people :mrgreen:

Back on topic, I've never actually used a finally block... Wouldn't it have the same effect just omitting any returns on your catch and letting the code run on?
The catch will prevent the code from halting by any caught exceptions... If your catch has no return, why do you need finally?

In a nutshell, same question as OP... I still didn't get it :wink:

Cheers
The next sentence is the truth. - The previous sentence is a lie.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6598
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: try catch finally

Postby Thesh » Tue Jan 18, 2011 10:56 pm UTC

Finally runs no matter what. Uncaught exception? It runs. Return statement? It runs. Catch throws an exception? It runs. You should put all your cleanup code inside the finally.

Take this code:

Code: Select all

bool SomeFunction(ConnString) {
   SqlConnection Connection = new SqlConnection(ConnString);
   Connection.Open();
   try
   {
      SqlCommand Command = new SqlConnection("SELECT Column2 FROM Table WHERE KeyColumn = 1", Connection)
      int a = (int)Command.ExecuteScalar();

      if (a == 1)
      {
         //Do something
      }
      else if (a == 2)
      {
         throw new Condition2Exception();
      }
      else {
         return false;
      }
   }
   catch (Condition2Exception e)
   {
      //Handle The Exception
      return false;
   }
   finally
   {
      Connection.Close();
   }

   return true;
}


Command.ExecuteScalar can have two possible exceptions, neither of which are caught, there may be other exceptions that you can't in the rest of the code, the function may return in the try. In any case, you can be sure that Connection.Close() will be called without having to catch generic exceptions (which is bad practice), and you can keep all your cleanup code in one place.
Summum ius, summa iniuria.

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: try catch finally

Postby TheChewanater » Wed Jan 19, 2011 3:07 am UTC

Thesh wrote:Finally runs no matter what. Uncaught exception? It runs. Return statement? It runs. Catch throws an exception? It runs. You should put all your cleanup code inside the finally.

StackOverflowException?

Code: Select all

bool foo () { return foo (); }

void lauchNukes () {
  Bomb b = new NuclearBomb ();
  b.activate ();
  
b.setLaunch (true);

  try
  
{
    if (foo ())
      
b.setLaunch (false);
  }
  catch (Exception e)
  {
    return;
  }
  finally
  
{
    b.disactivate ();
  }
}
 
ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
phlip
Restorer of Worlds
Posts: 7573
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: try catch finally

Postby phlip » Wed Jan 19, 2011 3:40 am UTC

Yep:

Code: Select all

activate() called
setLaunch(true) called
deactivate() called
Exception in thread "main" java.lang.StackOverflowError
        at Bomb.foo(Bomb.java:8)
        at Bomb.foo(Bomb.java:8)
        at Bomb.foo(Bomb.java:8)
        [snip many many rows]
        at Bomb.foo(Bomb.java:8)
        at Bomb.foo(Bomb.java:8)


However, some things that don't cause the finally to run include:
System.exit();
JVM crash
Ctrl+Alt+Del->End Process, or killall java
Pulling the power cord out of your computer

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
TheChewanater
Posts: 1279
Joined: Sat Aug 08, 2009 5:24 am UTC
Location: lol why am I still wearing a Santa suit?

Re: try catch finally

Postby TheChewanater » Wed Jan 19, 2011 4:28 am UTC

ImageImage
http://internetometer.com/give/4279
No one can agree how to count how many types of people there are. You could ask two people and get 10 different answers.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6598
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: try catch finally

Postby Thesh » Wed Jan 19, 2011 4:43 am UTC

Yeah, the exceptions to the rule are, of course, anything that's impossible to recover from.
Summum ius, summa iniuria.

User avatar
mister_m
Posts: 34
Joined: Fri Feb 04, 2011 2:51 am UTC

Re: try catch finally

Postby mister_m » Fri Feb 04, 2011 3:12 am UTC

I can give you an example of where using a finally block came in handy recently in school. I am taking a distributed systems class and we were tasked with building a TCP client and server program to transfer files from one to the other. What was key here, is that in the event of an exception occurring, we needed to close the sockets that were currently open. Leaving the socket open and simply failing is a no-no.

For example: If I was a client application that just told the server that I wanted fileX.y, I would expect the server to send me back the length of the file in bytes. If I did not receive anything from the client I would have to catch an exception, do something (in my case, just print the error to the screen as the assignment parameters required, and then close the connection in the finally block.

kalleguld
Posts: 2
Joined: Fri Feb 11, 2011 7:09 am UTC

Re: try catch finally

Postby kalleguld » Fri Feb 11, 2011 7:21 am UTC

Thesh wrote:Yeah, the exceptions to the rule are, of course, anything that's impossible to recover from.

It's not impossible. When you enter the try-block, you just flash the finally-code onto the BIOS, and it's run the next time you boot :)

User avatar
Yakk
Poster with most posts but no title.
Posts: 11129
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: try catch finally

Postby Yakk » Sat Feb 12, 2011 6:11 pm UTC

Note that RAII (resource allocation is initialization) is an alternative to the try-catch-finally pattern.

RAII means that you stuff resources that need to be cleaned up in automatically cleaned up objects on the stack, and the clean up code goes into the object clean up code. In the event of an exception, the stack is unwound and the RAII objects are destroyed, cleaning up the resource they allocated.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 7 guests