繁体   English   中英

Java:关闭流后使引用为null

[英]Java: Making reference null after closing stream

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

例:

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

// code

input.close();
input = null;

// possible more code

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

资源处理应在标准的acquire(); try { use(); } finally { release(); } acquire(); try { use(); } finally { release(); } 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的Parameterise。

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(); } try { ... finally { x.close(); } s。

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

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

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

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

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

  1. 在大多数情况下,无论如何它都会在之后超出范围
  2. 因此“释放”的记忆量是完全无关紧要的

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

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

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

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

其中Resource可以是您要使用的任何外部资源,例如InputStreamOutputStream ,Java IO API的ReaderWriter ,还有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提供了几种这样的实用方法。

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

但是,分配null并不总是不好的做法。 阅读Effective Java第2章的第6项

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM