views:

212

answers:

3

I have seen two ways of acquiring and disposing resources. Either:

Resource resource = getResource();
try { /* do something with resource */ }
finally { resource.close(); }

or:

Resource resource = null;
try { resource = getResource(); /* do something with resource */ }
finally { if (resource != null) resource.close(); }

I was wondering which style is preferable. The first one avoids the if condition, while the second one (I presume) handles the case of thread abort right after the assignment but before entering the try block. What other pros and cons do these styles have over each other? Which one should I preferably use?

A: 

If getResource() throws an exception then resource will be null, getResource() does not return anything in the case of an exception. So, as long as getResource() can throw an exception, always check for null before calling resource.close(). I feel the best way to organize this code is to put everything inside the try block; make it clear clear that getResource() throws exceptions.

ForYourOwnGood
There's no need to do this with the first version though - if the exception is thrown, you won't reach the finally block.
Jon Skeet
In similar code where, say, a lock is being acquired and released, a failure in acquisition would result in an unmatched release.
Tom Hawtin - tackline
+4  A: 

In C#, just use the using statement:

using (Resource resource = GetResource())
{
    /* Do something */
}

There's no risk of a thread abort in Java happening between the assignment and entering the try block - aborts only occur during sleeps and waits. EDIT: I can't actually find this in the spec, which is somewhat worrying. Hmm.

Jon Skeet
Thank you. C#'s using keyword is great, but sometimes it cannot be used (e.g. with a type that does not implement IDisposable, or when Dispose() should be called conditionally). As for Java, I have no experience actually with such issues, but can't a thread be interrupted?
Hosam Aly
they can be interrupted (safely) if you write code to allow it, what really happens is that threads can get signaled that they need to interrupt, and on the thread code you decide how you stop the current work being performed
BlackTigerX
Yes - but at least they won't get interrupted post-assignment, pre-entering-try-block. That's the important bit :)
Jon Skeet
May I ask how do you know they will not be interrupted between the assignment and the try?
Hosam Aly
@Hosam: As I said, I haven't managed to find it in the spec yet, but note that InterruptedException is a *checked* exception, so it can't just be thrown anywhere. I believe that *somewhere* it's documented to only be thrown during blocking operations (wait/sleep/IO etc).
Jon Skeet
Thanks Jon. You're helpful as always.
Hosam Aly
+3  A: 

first one is preferable

BlackTigerX
And for extra marks, make the local variable final.
Tom Hawtin - tackline