在finally块中将引用设置为null?

7
我的一个同事在finally块中将引用设置为null。我认为这是无意义的。
public Something getSomething() {
    JDBCConnection jdbc=null;
    try {
        jdbc=JDBCManager.getConnection(JDBCTypes.MYSQL);
        ...
    }
    finally {
        JDBCManager.free(jdbc);
        jdbc=null; // <-- Useful or not?
    }
}

您对此有何看法?


对于这个确切的代码,使用try/finally是没有意义的 - 如果getConnection抛出异常,jdbc将为null,因此free不会执行任何操作。可能在赋值和try结束之间确实有一些内容。 - Pete Kirkham
你的同事这样做的原因是什么? - Thorbjørn Ravn Andersen
我认为他认为这是“干净”的,并且可以节省内存。 - deamon
7个回答

13
你是正确的,jdbc 是一个局部变量,所以当 getSomething() 方法返回时,jdbc 将会超出作用域,并且可以被垃圾回收器回收。这实际上与将其设置为null相同。因此,在下一行代码中超出作用域时将变量设置为 null 没有意义。
最好的做法是将变量限制在需要的最小范围内,例如,如果你只需要在 for 循环内使用一个变量,那么就在 for 循环中声明它,当代码退出 for 循环时,它将会被垃圾回收器回收。 这样做不仅可以降低方法的复杂度,还可以减少设置本地变量为空的必要性,带来的好处是使你的代码更加模块化,易于阅读和维护。

5

由于它是局部变量,无论如何都会失去作用。这毫无意义。

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


2
是的,这几乎是无意义的。动机通常是为了“帮助”垃圾收集器,但这根本不是真正的帮助,因为引用无论如何都会被清除。虽然它不会造成任何伤害,至少对于VM来说不会,但你的眼睛和理智则是另一回事。
然而,这个例子并没有返回Something。如果这个例子是不完整的,并且实际上在finally块之后有语句,那么将jdbc设置为null可以作为使用的威慑力量,并且立即发生的NPE会告知在finally块之后的任何使用。

1
在这种特殊情况下,从技术上讲,它真的没有用。当方法返回时,jdbc不再存在,也不会持有连接的引用,因此不会影响垃圾回收。
这是一个编码风格的问题。如果有一天您在finally块之后添加更多代码,则有一个小优点。然后很明显,您不能再使用jdbc,因为它已经被JDBCManager释放了。
因此,将对已处理资源的引用置为空是一个好习惯。

+1 表示向程序员展示给定引用无效。 - Thorbjørn Ravn Andersen
谁给那个答案点了踩——我很想知道你的理由。真的! - Andreas Dolk

1

如已经写过的那样,在这种情况下它是无用的,因为该方法在 finally 后结束。
如果 try-finally 后面有代码需要最终防止其使用,我会这样做。而且也有(非常罕见的)情况可以帮助到它。
请看这篇文章:Java Memory Puzzle


0

然后他应该在所有方法中将所有本地变量设置为null,然后再返回。

JVM可能会优化掉这一行,因此它对运行时没有任何影响。


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

更重要的是 - 这将防止程序员在jdbc被释放后继续使用它。 - Andreas Dolk
1
不,这不会帮助垃圾回收清理。JVM规范非常清楚,只有对进一步计算有贡献的引用是可达的,因此如果将其设置为null并且不会得到NPE,则将其设置为null没有效果。如果你将其设置为null并且会得到NPE,则会破坏代码。更容易地,在声明和使用周围添加额外的{},或者更好地将其使用重构到单独的方法中,以在编译时确定它是否被使用。 - Pete Kirkham
如果你将其设置为null并且没有收到NPE,那是什么意思?将某物设置为null时不可能收到NPE。 - user207421
我也看到过多次将数字置空的情况,并对此感到困惑。A.3.3节讨论了支持这种答案的“隐形”对象。http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html - Glenn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接