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