Reputation: 7288
Whenever I see Java 6 Stream handling it's done pretty much like this:
public void myMethod() throws Exception
{
InputStream stream = null;
try
{
stream = connection.openConnection();
...
}
finally
{
if( stream != null )
{
stream.close();
}
}
}
But I fail to see why this is necessary. Wouldn't this work the same way?
public void myMethod() throws Exception
{
InputStream stream = connection.openConnection();
try
{
...
}
finally
{
stream.close();
}
}
If openConnection()
fails then stream
won't be assigned and then there's nothing to close anyway, isn't it?
Upvotes: 0
Views: 496
Reputation: 20618
Everytime you are retrieving an InputStream with a construct like
InputStream stream = connection.openConnection();
there are three possible outcomes: Either the method returns a proper InputStream
, or it returns null
, or it throws an exception.
Let's look at all three possibilities:
1) The method returned a proper input stream.
In that case the try block just continues, and if it does not encounter any other problems (aka exceptions), it just normally ends after also executing the finally block.
2) The method returns null.
In that case you also should have a null check inside the try block. If so, your try block normally just does nothing and the finally block must also have the null check. Otherwise your finally block would throw a NPE.
If you do not guard against the null return, your code inside the try block will throw the NPE (I assume the stream variable is used there). In that case, the finally block will be executed and would again throw a NPE, if it had not the null check. In the latter case, only the second NPE from the finally block is actually thrown to the caller.
3) The method call for retrieving the input stream throws an exception.
In that case the try block will end, which immediately causes the finally block to execute, and then the method will end abruptly. But with which exception? That depends.
Consider the thrown exception is an IOException, which in most cases will be thrown. First of all, the variable will still have the null reference! The finally block then would again throw an NPE, if it had not the null check. In that case, the first exception (the IOE) will be forgotten, because only the NPE would be passed to the called of your method. That's not a good idea.
All in all, the null check is indeed necesary.
Now comes Java 7 with its try-with-resources construct. This is indeed a much better mechanism, as it has an implicit finally block, where the streams are closed. If there is an exception in the try block, and the implicit finally block also throws an exception, tnow the first exception (from inside the try block) will be passed to the caller. That is much mor appropriate. And the syntax is much better to read.
Upvotes: 0
Reputation: 262494
I agree with you.
That extra step with the null
assignment is unnecessary and ugly. You can even make stream
final.
The only time I would write something like this is if you have more than one resource that needs to be cleaned up (happens with JDBC a lot), and you want to avoid multiple nested try/finally blocks (but usually I go for those anyway).
And with Java 7, you can use the try-with construct.
Upvotes: 4