开发者

What is the advantage of null assignment in Java?

开发者 https://www.devze.com 2023-02-13 06:26 出处:网络
I see a lot of code like this: SomeObject someObject = null; try{ someObject = ObjectFactory.createSomeObject();

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 nulls 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消