Java中空赋值的优点是什么?

Java中空赋值的优点是什么?,java,Java,我看到很多这样的代码: SomeObject someObject = null; try{ someObject = ObjectFactory.createSomeObject(); ... 与此相比,这样做的优势是什么: SomeObject someObject = ObjectFactory.createSomeObject(); 它可能与someObject变量的作用域(可见性)有关,因此该变量可以稍后在try catch-block之外使用。这是一个常用的习惯用

我看到很多这样的代码:

SomeObject someObject = null;

try{

   someObject = ObjectFactory.createSomeObject();
   ...
与此相比,这样做的优势是什么:

SomeObject someObject = ObjectFactory.createSomeObject();

它可能与someObject变量的作用域(可见性)有关,因此该变量可以稍后在try catch-block之外使用。

这是一个常用的习惯用法,您必须使用null初始化连接,因为Java只支持类成员的初始化,在此范围内,必须使用
null
对其进行初始化,因为
ConnectionFactory.create()
可能还会引发异常

您可以使用它来扩大变量的范围,并在以后使用它,例如关闭连接句柄

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()
    }
}

如果在catch块内初始化连接,则finally块或以下代码将不可见。

这是创建需要销毁的对象或需要处置的资源时的常见模式。例如,对于数据库连接:

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();
}
如果在
try
块中声明对象,则不能在
finally
中引用它们,因为它具有不同的作用域。声明需要在
try
外部,但赋值需要在内部,以便捕获初始化期间的异常


close()
调用必须在
finally
块内完成,以确保无论数据库调用是否成功,都能释放数据库资源。

如果要在try/catch/finally块中处理的ObjectFactory.createSomeObject()方法可能引发异常,这是退出try/catch/finally块后使用someObject的唯一方法。

使用try-catch-finally块,可以更轻松地处理发生的任何异常


不能在try块内声明变量,也不能在该块外访问它。所以,你可以在任何块之外声明它。当您想在finally块中释放资源时,这尤其有用。

人们玩
null
s试图将
try
-
finally
try
-
catch
合并,这是一种不明智的小舞蹈。它经常伴随着bug(NPE,在不愉快的情况下不关闭所有东西,释放未获得的资源,等等——人们对草率代码中的bug非常有创造力)。最好将两种不同形式的
try
拆分为不同的方法。与
try
-
catch
-
finally
组合不同,
finally
应该在
catch

try {
    final SomeObject someObject = ObjectFactory.createSomeObject();
    try {
        ...
    } finally {
        someObject.dispose();
    }
} catch (SomeException exc) {
    throw AppropriateToTheCallerException(exc);
    // or printf
}
在JDK7中,假设
SomeObject
实现了
AutoCloseable
,您可以编写

try (final SomeObject someObject = ObjectFactory.createSomeObject()) {
    ...
} catch (SomeException exc) {
    throw AppropriateToTheCallerException(exc);
    // or printf
}

请注意,隐藏的“finally”位于
catch
之前。我通常会建议将资源和异常处理分开。

要点是:如果在
try
子句中声明了
connection
,则其范围将限于该子句-因此您不能在
finally
子句外部关闭它。这是一个示例,这不是对这样做的好处的回答。这是一个常见的“反习惯用法”。除此之外,它往往会导致错误的实现。例如,如果语句抛出,代码不会关闭连接。