Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:关闭流后使引用为空_Java - Fatal编程技术网

Java:关闭流后使引用为空

Java:关闭流后使引用为空,java,Java,关闭流引用后将其设置为null是一种好的做法吗?这会以任何方式释放资源吗 例如: BufferedReader input= new BufferedReader(new FileReader("myfile.txt")); // code input.close(); input = null; // possible more code 不,这是坏习惯。IMO,你甚至应该考虑制作变量最终< /代码> .< 应在标准acquire()中处理资源处理;尝试{use();}最后{relea

关闭流引用后将其设置为null是一种好的做法吗?这会以任何方式释放资源吗

例如:

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

// code

input.close();
input = null;

// possible more code

不,这是坏习惯。IMO,你甚至应该考虑制作变量<代码>最终< /代码> .< 应在标准
acquire()中处理资源处理;尝试{use();}最后{release();}
方式。在这种情况下:

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

    // code

} finally {
    rawIn.close();
}
实际上,这段代码将拾取任何设置为默认的字符编码。我建议显式使用特定的硬编码字符集或上面的参数

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

    // code

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

对于输出,您通常应该在正常事件过程中
flush
。但在异常情况下通常不这样做。实际上
close
通常执行
flush
,因此您不应该在异常情况下关闭它们。如果装饰程序都
flush
并且拥有资源,那么您将不得不露齿而笑。


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

不需要。只需
input.close()
就足够了。记住在
finally
块中执行此操作总是明智的。在调用
close()之前,最好执行如下空检查

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

除非您手动管理一个资源池(处理您自己的内存),否则没有必要为输入流设置空值。理想情况下,您使用的任何函数都很小,并且当对象超出范围时,对该对象的引用将消失,并将其标记为垃圾收集


我提到了资源池,就好像您天真地关闭了流而没有使对象为空一样,您可能会意外地保留一个您实际上并不需要的对象引用。

这可能会使流对象本身符合垃圾收集的条件,但是

  • 在大多数情况下,不管怎样,它都会超出范围
  • 这样“释放”的内存量是微不足道的

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


    但是分配
    null
    并不总是一种不好的做法。请阅读中的第6项。不,它不是。
    close()
    已经释放了资源。正常做法如下:

    Resource resource = null;
    try {
        resource = new Resource();
        // ...
    } finally {
        if (resource != null) try { resource.close(); } catch (ResourceException logOrIgnore) {}
    }
    
    其中,
    Resource
    可以是您想要使用的任何外部资源,例如Java IO API的
    InputStream
    OutputStream
    Reader
    Writer
    ,但也可以是JDBC API的
    Connection
    Statement
    ResultSet

    在设计良好的代码中,内存不是问题。如果代码离开了方法块,那么它已经符合GC的条件

    您可以将
    close()
    重构为如下实用程序方法:

    public static void close(Closeable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (ResourceException logOrIgnore) {
                // Log it?
            }
        }
    }
    
    您可以按如下方式使用:

    } finally {
        close(resource);
    }
    

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

    @Hei:欢迎使用SO。只是为了将来(如果您编辑此问题),您可以用四个空格缩进代码行,它们将显示在特殊的代码块中,这使它们更易于阅读。感谢您的评论,我将在以后的问题中对此进行研究。如果您在try块之前执行原始赋值,则不需要空值检查。只有当文件无法打开时,才会失败,在这种情况下无论如何都没有问题。好吧,不是马上。在后续收集中释放内存之前,它必须经过最终确定。或者,您可以将资源获取放在正确的位置w.r.t.
    try
    。公平点,但有时您希望在相同的
    try
    块中捕获、记录和/或重新显示异常,如果有必要,作为另一种例外。将船推出!使用两个
    try
    块!!!然后使用Execute-Around成语。是的,我在这里见过(顺便说一句)。感谢您再次提醒:)(+1)。+1用于在流声明中使用
    final
    。-1用于关闭内部(
    rawIn
    )流。您应该始终关闭最派生的流。例如,在您的情况下,
    BufferedReader
    的内部缓冲区中可能有一些数据。在
    中调用关闭
    ,将正确刷新此数据。调用关闭
    rawIn
    将放弃此数据。感谢您的回答,并提到了一个取消为空的情况好主意。@Alexander是对的。
    BufferedReader
    不过是一个很差的例子。不如用
    BufferedWriter
    和小于8KB的内容来测试它。@BalusC你确实调用了
    flush
    ,不是吗?不,我希望
    close()。