Java:关闭流后使引用为null

时间:2010-03-22 19:50:51

标签: java

关闭它们后将流引用设置为null是一个好习惯吗?这会以任何方式释放资源吗?

示例:

BufferedReader input= new BufferedReader(new FileReader("myfile.txt"));

// code

input.close();
input = null;

// possible more code

6 个答案:

答案 0 :(得分:6)

不,这是不好的做法。 IMO,你甚至应该考虑制作变量final

资源处理应以标准acquire(); try { use(); } finally { release(); }方式处理。在这种情况下:

final Reader rawIn = new FileReader("myfile.txt"); // Character encoding??
try {
    BufferedReader in = new BufferedReader(rawIn);

    // code

} finally {
    rawIn.close();
}

实际上,此代码会选择默认设置的任何字符编码。我建议明确使用特定的硬编码字符集或来自Above的参数化。

final InputStream rawIn = new FileInputStream("myfile.txt");
try {
    BufferedReader in = new BufferedReader(
        new InputStreamReader(rawIn, "UTF-8")
    );

    // code

} finally {
    rawIn.close();
}

您不应该在try块之外(以及在资源分配之前)创建包装器流/读取器,因为它们可能会抛出。类似地,他们的关闭可能会抛出(这实际上是BufferedOutputStream中的一个错误,可能会引发flush)。某些输入流可能包含其他资源,因此您需要两个try { ... finally { x.close(); } s。

对于输出,您通常应该在正常的事件过程中flush。但一般不要在特殊情况下。确实close通常会flush,因此在特例情况下你不应该关闭它们。如果装饰者flush并拥有资源,那么你将不得不咧嘴一笑。

在很少见的情况下,归零是一个好主意。例如,如果变量是对大对象的唯一引用,并且您要创建一个新的大对象来分配它,那么最好清除引用以允许在分配新对象之前回收旧对象。

答案 1 :(得分:5)

不需要。只需input.close()即可。请记住,在finally块中执行此操作总是明智的。在调用close()之前,最好像这样进行空检查

finally{
  if(input!=null){
    input.close();
  }
}

答案 2 :(得分:3)

它可能使Stream对象本身有资格进行垃圾回收,但

  1. 在大多数情况下,无论如何它都会超出范围
  2. 因此“释放”的记忆量非常微不足道

答案 3 :(得分:1)

除非你手动管理一个rosources池(处理你自己的内存),否则没有必要使输入流为空。理想情况下,您所处的任何函数都很小,并且当对象超出范围时,对对象的引用将会死亡,无论如何都要将其标记为垃圾收集。

我提到了池化资源,好像你天真地关闭了流而没有使对象无效,你可能会意外地抓住你实际上并不需要的对象的引用。

答案 4 :(得分:1)

不,不是。 close()已经释放了资源。通常的做法如下:

Resource resource = null;
try {
    resource = new Resource();
    // ...
} finally {
    if (resource != null) try { resource.close(); } catch (ResourceException logOrIgnore) {}
}

Resource可以是您要使用的任何外部资源,例如Java IO API的InputStreamOutputStreamReaderWriter ,还有例如JDBC API的ConnectionStatementResultSet

在精心设计的代码中,内存不是问题。如果代码离开方法块,则它已经符合GC的条件。

您可以将close()重构为实用工具方法,例如:

public static void close(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (ResourceException logOrIgnore) {
            // Log it?
        }
    }
}

您可以使用如下:

} finally {
    close(resource);
}

Apache Commons提供了几种类似的实用方法。

答案 5 :(得分:0)

在这种情况下不需要,垃圾收集器会收集它。

但是,分配null并不总是不好的做法。阅读Effective Java, chapter 2

中的第6项