try-with-resources and null resource
Gernot Neppert
mcnepp02 at googlemail.com
Fri Jan 28 02:20:23 PST 2011
2011/1/28 Rémi Forax <forax at univ-mlv.fr>:
> Le 28/01/2011 10:30, Florian Weimer a écrit :
>
> [...]
>
>> By the way, has anybody else seen this phenomenon in their code base?
>>
>> InputStream in = null;
>> try {
>> in = new FileInputStream(path);
>> useFile(in);
>> } finally {
>> if (in != null) {
>> in.close();
>> }
>> }
>>
>> I'm wondering where this is coming from.
>
> You mean, instead of:
>
> InputStream in = new FileInputStream(path);
> try {
> useFile(in);
> } finally {
> in.close();
> }
>
>
> This code is very common. I've spied my students to understand why.
> It's because FileInputStream throws an exception so
> you put it in the try block, after all try/finally is like try/catch.
Yes, mostly this will be coupled with a 'catch' in order to deal with
checked exceptions.
Thus, instead of the canonical:
try {
final InputStream in = new FileInputStream(path);
try {
useFile(in);
} finally {
in.close();
}
} catch(IOException e)
{
...
}
...people end up writing the deceptively 'more concise':
InputStream in = null;
try {
in = new FileInputStream(path);
useFile(in);
} catch(IOException e)
{
...
} finally {
if(in != null) in.close();
}
...which is all but impossible to get right if more than one resource
is involved!
> Then the IDE warn you that 'in' is not accessible in
> the finally block. So you put the declaration on top of the block.
>
> InputStream in;
> try {
> in = new FileInputStream(path);
> useFile(in);
> } finally {
> in.close();
> }
>
> Here the IDE says that 'in' is not initialized if new FileInputStream
> throws an exception. So you initialize 'in' to null.
> And the IDE warn you because in.close() will throw a NPE.
> So you add a null check.
>
> It's the IDE's fault because it should not suggest to initialize 'in'
> with null and developer's fault because he blindly follows what the IDE
> says.
>
> Rémi
It's not just the IDE that warns you. Once you decide to put the
Variable declaration before the 'try' block, then you _must_
initialize the variable with 'null'. Otherwise, there'd be a codepath
that would leave it uninitialized: if the constructor throws, the
assignment will be skipped! Then, the 'finally' block has to be able
to deal with the 'null' case.
More information about the coin-dev
mailing list