I see a lot of code like this:
SomeObject someObject = null;
try{
someObject = ObjectFactory.createSomeObject();
...
What is the advantage of doing this开发者_StackOverflow中文版 compared to this:
SomeObject someObject = ObjectFactory.createSomeObject();
This is an common used idiom, you have to initialize the connection with null, because Java only support initialization for class members, in this scope you have to initialize it with null
, because ConnectionFactory.create()
maybe also throws an exception.
You use this to widen the scope of your variable and use it later, for example to close your connection handle.
Connection connection = null;
try {
connection = ConnectionFactory.create();
[...]
// More code which probably causes an exception
} catch(Exception e) {
// Handle the exception
} finally {
if(connection != null) {
// Cleanup and close resources later
connection.close()
}
}
If you initialize the connection within the catch block it is not visible for the finally block or the following code.
It's a common pattern when creating objects that need to be destroyed or resources that need to be disposed of. For instance, with database connections:
Connection connection = null;
PreparedStatement statement = null;
try {
connection = getConnection();
statement = connection.prepareStatement("SELECT * FROM users");
// ...
}
catch (SQLException exception) {
// Handle error.
}
finally {
if (statement != null) statement .close();
if (connection != null) connection.close();
}
If you declare the objects inside of the try
block then they cannot be referenced inside the finally
since it has a different scope. The declarations need to be outside the try
but the assignments need to be inside so that exceptions during initialization can be caught.
The close()
calls must be done inside of a finally
block to ensure that the database resources are freed whether or not the database calls succeed.
It's probably related to the scope (visibility) of the someObject-variable, so the variable can be used later on outside the try-catch -block.
It's an ill-advised little dance people play with null
s in an attempt to merge a try
-finally
with a try
-catch
. It's frequently accompanied by bugs (NPE, not closing everything in the unhappy case, releasing resources not acquired, etc. - people are so inventive with bugs in sloppy code). Much better to split the two different forms of try
, possibly into different methods. Unlike the try
-catch
-finally
combo, the finally
should be within the catch
.
try {
final SomeObject someObject = ObjectFactory.createSomeObject();
try {
...
} finally {
someObject.dispose();
}
} catch (SomeException exc) {
throw AppropriateToTheCallerException(exc);
// or printf
}
In JDK7, assuming SomeObject
implements AutoCloseable
you can write
try (final SomeObject someObject = ObjectFactory.createSomeObject()) {
...
} catch (SomeException exc) {
throw AppropriateToTheCallerException(exc);
// or printf
}
Note that the hidden "finally" goes before the catch
. I would generally suggest separating resource and exception handling.
If an exception might be thrown in the ObjectFactory.createSomeObject() method that you want to handle in your try/catch/finally block, this is the only way you can use someObject after exiting the try/catch/finally block.
Using the try-catch-finally blocks, you can more easily handle any exceptions that occur.
You can't declare the variable inside the try block and access it outside of that block. So, you declare it outside any block. This is particularly helpful when you want to release resources in a finally block.
精彩评论