Please: try-with-resouces Lock support!
brucechapman at paradise.net.nz
brucechapman at paradise.net.nz
Wed Mar 9 13:17:18 PST 2011
Quoting Reinier Zwitserloot <reinier at zwitserloot.com>:
> This snippet:
>
> try (Resource r = getResource()) {
> .....
> } catch (SomeException e) {
> ... do something with r....
> }
>
>
> implies that getResource() is not expected to fail. This is quite
> different
> from for example an inputstream:
implies how?
Neal's post which you quote suggested to me the perspective that in t-w-r, any
catch or finally clause is really about the resource initialisation (and
closing), and NOT really (or at least not so much) about exceptions thrown in
the block. If you want to catch exceptions in the block, use the nested try
idiom suggested by Stephen's email and confirmed by Neal. This is not obvious.
But your statement 'implies that getResource() is not expected to fail.' is not
consistent with this perspective because you have a catch in the t-w-r, which
signifies that you are expecting getResource() to fail (assuming any expected
failure of close() doesn't need explicit handling).
If the perspective above is correct (I am not saying it is - I am suggesting it
might be), or at least leads to correct code, then maybe we should give a hint
of that in the JSR spec so we (and people who will write books about this stuff,
and people that will explain it to others) send people off in the right
direction to start with.
Then again, I may well be deluded.
Bruce
>
> try (InputStream r = new FileInputStream(file)) { ... }
>
> where an exception on the constructor call is expected and the current
> specified behaviour of ARM matches this expectation (notably: that it
> includes the initializing expression as part of the 'try').
>
> There are a few solutions when the expectation is for the expression not
> to
> fail as in the getResource example:
>
> (1) Do *NOT* consider the expression as part of the 'try'. Short of
> introducing some new keyword to specify which behaviour you want,
> Stephen's
> example of try (Resource r = ...) { try { ..... }} does exactly that,
> and is
> the only way to do this.
>
> (2) Allow both with the same try statement. However, as in practice any
> expression can theoretically fail with any exception, the solution
> would
> have to be that 'r' is set to null if the initializing expression does
> not
> complete normally. The syntax sugar to make this work isn't trivial but
> it
> can be done.
>
> One could then write:
>
> try (Resource r = getResource()) {
> ....
> } catch (Exception e) {
> icon = Icons.DEFAULT_ICON;
> logger.log("App icon resource " + r.getURL() + " is not available",
> e);
> }
>
> and if the exception that triggered the catch block to run occurred in
> the
> evaluation of "getResource()", the above code would produce an NPE on
> the
> log line. Better than a core dump, I guess. As with any null resource,
> such
> a resource will not be closed, and no exception is caused by the fact
> that
> 'r' is null when its time to clean it up. (which would be following the
> execution of the catch block).
>
> Whether doing this is a good idea is something I leave to the readers,
> but
> it is another consistent alternative and does look slightly cleaner,
> though
> there's far more magic going on with this version.
>
>
> --Reinier Zwitserloot
>
>
>
> On Sat, Mar 5, 2011 at 9:18 PM, Neal Gafter <neal at gafter.com> wrote:
>
> > In the try-with-resource language construct, exceptions thrown during
> the
> > construction of the resource are caught in the catch clauses.
> Therefore,
> > making the resource in scope be within the catch clause would be
> providing
> > access to a variable that is not definitely assigned. Since a
> variable
> > that
> > is final (by the try-with-resources specification), not definitely
> assigned
> > (because the exception might have occurred during the resource
> expression),
> > and not definitely unassigned (because the exception might have
> occurred
> > during the try block), it cannot be used in any way. There is
> therefore no
> > point in making the variable be in scope within the catch clause.
> >
> > The correct thing to do is Stephen' suggestion:
> >
> > On Sat, Mar 5, 2011 at 11:08 AM, Stephen Colebourne
> <scolebourne at joda.org
> > >wrote:
> >
> > > But there is a "hack" solution:
> > >
> > > try(Resource r = getResource()) {try {
> > > doSomething(r);
> > > } catch (ResourceException e) {
> > > System.out.println(e + " from " + r); // r undefined here
> > > }}
> > >
> > > Not ideal.
> > >
> >
> > This is the correct solution, and it is both ideal and not a hack. I'm
> not
> > sure I agree with your spacing and placement of curly braces, but that
> is a
> > style issue. The semantics of this code are different (than a catch on
> the
> > try-with-resources statement) because the catch clause here only
> catches
> > exceptions thrown from within the inner try block. If you want to use
> the
> > resource variable, that is exactly what you need.
> >
> > At worst, this exchange demonstrates that the try-with-resources
> > specification is piling too much complexity on the already overly
> complex
> > try statement.
> >
> > Cheers,
> > Neal
> >
> >
>
>
More information about the coin-dev
mailing list