In C++, the ResourceAcquisitionIsInitialization idiom is widely used for this, which works because of explicit object lifetimes (objects have destructors which are called when they go out of scope or are deleted; those can release resources at that time).
Java automates the reclamation of memory, but not other resources. A finalize() method can help ensure that resources are released eventually but not in a timely fashion. It appears that this has been handled ad-hoc in various Java classes -- some have close(), some dispose(), some destroy(), and probably others.
I haven't come up with an elegant general solution to this, and wonder if anyone else has.
-- JimPerry
If an attempt to allocate a resource fails, it may be worth requesting a GC and calling finalizers, and trying again.
Slightly more interesting is to protect your resource with inner classes. Like:
interface Closure { void exec(); }Now acquires and releases are guaranteed to be paired. -- DaveHarrisclass Resource { private abstract void acquire(); private abstract void release();
public void withDo( Closure c ) { acquire(); try { c.exec(); } finally { release(); } } } void test( Resource r ) { r.withDo ( new Closure() { void exec() { System.out.println( r ); // or whatever } } ); }
The example by DaveHarris above is similar to one I came up with a couple of days ago in a discussion in the Comp.object news group. The difference is that ResourceReleasesResource attempts to be abstract and reusable by multiple resource providers. Any object can be a resource client if it implements the ResourceClient interface. (This seems more general than an inner class.)
To me, close(), destroy(), etc have different meanings. In most cases, I think close() is appropriate (open files, sockets, db connections, etc). I do have cases where I use something else instead. For instance, destroy() to me means that some object (ie an object that has a temporary file) actually has to go out and free resources from somewhere else.
This page mirrored in JavaIdioms as of April 29, 2006