Proposal: Automatic Resource Management

Peter Levart peter.levart at gmail.com
Thu Apr 2 12:30:10 PDT 2009


Hello Coiners!

I played with ARM a little more and also considered Reinier Zwitserloot's
remarks to
my idea of making ARM more SARM (Semi Automatic Resource Management).
I apologise again of accusing Bob Lee's example as flawed. Now that I fully
understand
Joshua Bloch's ARM proposal, I'm convinced that it's exception suppressing
logic
is correct for most usage scenarios.

One weakness that the ARM spec does not address yet is about how
AutomaticResource interface should be handled in obscure situations of
multiple
inheritance.

So I'm still trying to get rid of the need for special interface altogether.

Here's my second take:

        try (InputStream in = new FileInputStream(inputFile); in.close())
        {
            // try block
        }
        catch(IOException e)
        {
            // catch block
        }
        finally
        {
            // finally block
        }

... to be translated into:

        try
        {
            InputStream in = new FileInputStream(inputFile);
            boolean $$suppress = false;

            try
            {
                // try block
            }
            catch (final Throwable $$t)
            {
                $$suppress = true;
                throw $$t;
            }
            finally
            {
                if ($$suppress)
                    try { in.close(); } catch (Throwable $$ignore) {}
                else
                    in.close();
            }
        }
        catch (IOException e)
        {
            // catch block
        }
        finally
        {
            // finally block
        }

... that's not much different from Joshua's original proposal. In fact it
uses the same
exception suppressing logic. There are only 3 differences:

- does not use a special interface
- disposal is explicit (Semi Automatic)
- handles only a single resource

But with both "catch" and "finally" parts as optional, the following:

        try (InputStream in = new FileInputStream(inputFile); in.close())
        {
            // try block
        }

... is translated into:

        {
            InputStream in = new FileInputStream(inputFile);
            boolean $$suppress = false;

            try
            {
                // try block
            }
            catch (final Throwable $$t)
            {
                $$suppress = true;
                throw $$t;
            }
            finally
            {
                if ($$suppress)
                    try { in.close(); } catch (Throwable $$ignore) {}
                else
                    in.close();
            }
        }

... and so, single-resource SARM constructs can then be nested to construct
for example this:

        try (InputStream in = new FileInputStream(inputFile); in.close()) {
            try (OutputStream out = new FileOutputStream(outputFile);
out.close()) {
                // try block
            }
        }
        catch(IOException e)
        {
            // catch block
        }

... one more with locking:

        ReadWriteLock rwl = ...

        try (rwl.writeLock().lock(); rwl.writeLock().unlock()) {
            i++;
        }

That's it. What dou you think?

Regards, Peter



More information about the coin-dev mailing list