RFR JDK-8080641: JEP-JDK-8042880 : Implement new tests on Project Coin

Alex Buckley alex.buckley at oracle.com
Fri Oct 16 21:41:13 UTC 2015


On 10/16/2015 1:20 PM, Sergei Pikalev wrote:
> I've fixed all remarks you've send me except one. I'd like to ask you
> about it.
>
>> - What's truly new when a try (...) header uses a resource variable
>> declared outside the 'try'? Answer: no exception can be thrown,
>> whereas the declaration of a resource variable by 'try' includes an
>> initializer expression that can throw an exception. There should be a
>> test to "prove" that try (r1) {...} doesn't throw exceptions from
>> resource initialization, and that try (r1; AutoCloseable r2 = ...)
>> {...} only throws exceptions due to r2's initialization.
>
> I can imagine just one case of variables where r1 could throw something.
> It's r1 = null case.
> So try (r1) {...} throws NullPointerException and catch block catches
> it. Also the case
> try (r1; AutoCloseable r2 = ...) {...} catches NullPointerException
> because it is thrown first.
> In other cases we have either correctly initialized r1 in try(r1) block
> or stop execution on
> exceptions with initialization of r1 before try(r1) {...} block.
>
> What do you really meant here?

Remember that a resource variable can be initialized to null. There's 
nothing wrong with that. It simply means the resource won't be closed 
automatically. See JLS8 14.20.3. Nothing has changed in this regard for 
SE 9.

What you're trying to "prove" is that this code -- try (r1) {} -- never 
throws any exceptions at run time regardless of the value of r1. Not 
from resource initialization, not from the try block, not from resource 
closure. I'm assuming the close() method in question doesn't throw 
anything, like Scanner::close. The number of resources can be increased, 
in both the old and new styles -- try (r1; AutoCloseable r2 = r1; 
AutoCloseable r3 = r2; r4) {}.

For try (r1) {} -- the single resource is ALWAYS initialized, and the 
try block is ALWAYS reachable (look at the translation in 14.20.3.1), 
and the single resource is ALWAYS closed provided it's non-null. Before 
SE 9, it was NOT true that a resource is ALWAYS closed because of the 
possibility that the resource failed to initialize. (Yes, if it did 
initialize to a non-null value, then it would always be closed, but 
initialization could prevent r1.close() ever being run.) So, another 
test should prove that r1's close() method is always run.

Now consider this extension -- try (r1; AutoCloseable r2 = 
alwaysBlowUp()) {}. This t-w-r will always initialize the first resource 
and ALWAYS close the first resource (provided r1 is non-null) even if 
the second resource failed to initialize. So regardless of the 
exceptions from r2's initialization, r1.close() will always be run.

Regarding the kind of variable that r1 is -- we talked about it being an 
array component, and it should also be a local variable that's not 
definitely assigned and a blank final field that's not definitely assigned.

Alex


More information about the compiler-dev mailing list