tags:

views:

387

answers:

4

In C++ we acquiring a resource in a constructor and release it in a destructor.

So when an exception rises in a middle of a function there will be no resource leak or locked mutexes or whatever.

AFAIK java classes don't have destructors. So how does one do the resource management in Java.

For example:

public int foo() {    
    Resource f = new Resource();
    DoSomething(f);
    f.Release();
}

How can one release resource if DoSomething throws an exception? We can't put try\catch blocks all over the code, can we?

+5  A: 

Yes you can and should put try/catch/finally block around your code. In C# there is a shorthand "using" statement, but in Java you are stuck with:

public int foo() {
    Resource f = new Resource();
    try {
        DoSomething(f);
    }
    finally {
        f.Release();
    }
}
qbeuek
A: 

If you want the using block get involved in the java closure debate :S

svrist
where is that debate at?
Spoike
All over the internet: http://www.google.dk/search?q=java+closures
svrist
A: 

Sorry to disappoint you but in Java we do use try\catch\finally blocks a lot. And with "a lot", I mean A LOT. I do sometimes wish that Java has the C# using block. Most of the time you won't need to free up resources as Java's garbage collector will take care of that.

However exceptions do have their uses in making error handling a lot cleaner. You can write your own exceptions and catch them for whatever you are doing. No more returning arbitrary error codes to the user!

Spoike
Yes! Let's start returning them ugly confusing stack traces to them!
Vinko Vrsalovic
Ah the wonders of getting a NullPointerException rather than a -429321313 Error code dialog. Makes me proud to be a developer :)
Free Wildebeest
Java 7 will have "resources management", a feature that will close all `Closeable` resources when one uses a special form of `try` block.
java.is.for.desktop
@Vinko: Error codes are worthless in comparison to stack trace dumps. Also if you're returning stack traces to the user you're doing something wrong, this is why we have "logger frameworks". ;P
Spoike
@Spoike: swooosh!
Vinko Vrsalovic
+2  A: 

It is possible to factor out try/finally (and exception and algorithms) using the Execute around idiom. However the syntax is highly verbose.

public int foo() {
    withResource(new WithResource() { public void run(Resource resource) {
        doSomething(resource);
    }});
}

...

public interface WithResource {
    void run(Resource resource);
}

public static void withResource(WithResource handler) {
    Resource resource = new Resource();
    try {
        handler.run(resource);
    } finally {
        resource.release();
    }
}

This sort of thing makes more sense if you are abstracting more than try/finally. For instance, with JDBC you can execute a statement, loop through the results, close resources and wrap the exception.

Tom Hawtin - tackline
with(new Resource() { public void do(Resource resource) .... reads slightly better. :-)
binil
It does, but it's wrong in more than one way. ;)
Tom Hawtin - tackline