7

null我的一位同事在 finally 块中设置了引用。我认为这是无稽之谈。

public Something getSomething() {
    JDBCConnection jdbc=null;
    try {
        jdbc=JDBCManager.getConnection(JDBCTypes.MYSQL);
        ...
    }
    finally {
        JDBCManager.free(jdbc);
        jdbc=null; // <-- Useful or not?
    }
}

你怎么看呢?

4

7 回答 7

13

你是对的,jdbc是一个局部变量,所以当getSomething()方法返回jdbc时将超出范围并且有资格进行垃圾收集,这实际上与将其设置为 null 相同。因此,当变量超出下一行代码的范围时,将变量设置为 null 是没有意义的。

将变量限制在所需的最小范围内是一种很好的做法,例如,如果您只需要在 for 循环中使用一个变量,然后在 for 循环中声明它,那么当代码退出 for 循环时,它将有资格进行垃圾回收。这一点,以及降低方法的复杂性,减少了甚至将局部变量设置为 null 的需要,并且作为一个好处,您的代码变得更加模块化,更易于阅读和维护。

于 2010-06-09T08:28:47.723 回答
5

由于它是一个局部变量,因此无论如何它都会超出范围。这是胡说八道。

如果它是一个长期存在的对象的实例变量(成员变量),它可能很有用,因为否则它可能会阻止垃圾收集器处理该对象。

于 2010-06-09T08:29:13.993 回答
2

是的,这几乎是无稽之谈。动机通常是“帮助”垃圾收集器,但这根本不是真正的帮助,因为无论如何都会清除引用。虽然它也没有什么害处,但至少对虚拟机没有害处——你的眼睛和理智是另一回事。

但是,该示例不返回Something。如果示例不完整,并且在 finally 块之后实际上有语句,则将 jdbc 设置为null可以起到阻止使用的作用,并且将发生的 NPE 会立即通知 finally 块之后的任何使用。

于 2010-06-09T08:29:03.617 回答
1

在这种特殊情况下,从技术上讲,它真的没用。当方法返回时,jdbc不再存在并且不会持有对连接的引用,因此不会影响垃圾回收。

这是编码风格的问题。如果有一天您在 finally 块之后添加更多代码,则有一个小优势。然后很明显你不能再使用jdbc了,因为它已经被 JDBCManager 释放了。

所以是的,取消对已处置资源的引用是一种很好的做法。

于 2010-06-09T08:36:19.653 回答
1

如前所述,在这种情况下它是无用的,因为该方法在 finally 之后结束。
如果在 try-finally 之后有代码,我会这样做,以最终阻止它的使用。并且在(非常罕见的)情况下它可以提供帮助。
看看这篇文章:Java 内存拼图

于 2010-06-09T09:41:27.063 回答
0

那么他应该在返回之前将所有方法中的所有局部变量设置为null。

JVM 可能无论如何都会优化这条线,所以它没有任何运行时影响。

于 2010-06-09T18:21:16.387 回答
-2

如果在 finally 块之后有更多代码而不是仅仅结束该方法,它可能会帮助垃圾收集器清理它。

于 2010-06-09T08:32:55.520 回答