在关闭流之后将流引用设置为null是一种好的做法吗?这样做会以任何方式释放资源吗?
例如:
BufferedReader input= new BufferedReader(new FileReader("myfile.txt"));
// code
input.close();
input = null;
// possible more code
在关闭流之后将流引用设置为null是一种好的做法吗?这样做会以任何方式释放资源吗?
例如:
BufferedReader input= new BufferedReader(new FileReader("myfile.txt"));
// code
input.close();
input = null;
// possible more code
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();
}
实际上,这段代码会选择默认的字符编码。我建议明确指定一个硬编码的字符集或从上面参数化。
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(); }
。
对于输出,通常应在正常情况下执行flush
。但通常在异常情况下不执行。实际上,close
通常会执行flush
,因此在异常情况下不应将其关闭。如果修饰符既具有flush
又具有资源,则必须咬紧牙关。
极少数情况下,清空变量是一个好主意。例如,如果变量是大对象的唯一引用,并且您将创建新的大对象来分配给它,最好清除引用以允许在分配新对象之前回收旧对象。
final
优秀,加1分。但是关闭内部(rawIn
)流则扣1分。应该总是关闭最终的流。例如,在您的情况下,BufferedReader
可能在其内部缓冲区中有一些数据。调用 in
上的 close 将正确地刷新此数据。调用 rawIn
上的 close 将丢弃它。 - Alexander PogrebnyakBufferedReader
是一个不好的例子。最好使用BufferedWriter
和少于8KB的内容进行测试。 - BalusCflush
吗? - Tom Hawtin - tacklineclose()
来完成它(因此在这个结构中不会发生)。 - BalusC不需要。只需要 input.close()
就可以了。记住最好在 finally
块内操作。在调用 close()
之前最好先进行 null 检查,方法如下:
finally{
if(input!=null){
input.close();
}
}
这可能会使Stream对象本身有资格进行垃圾回收,但是
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
。
在设计良好的代码中,内存不是问题。如果代码离开方法块,它已经可以进行垃圾回收。
您可以将 close()
重构为实用程序方法,例如:
public static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (ResourceException logOrIgnore) {
// Log it?
}
}
}
你可以按照以下方式使用:
} finally {
close(resource);
}
Apache Commons 提供了许多实用工具方法。
try
相关的正确位置。 - Tom Hawtin - tacklinetry
块中捕获、记录和/或重新抛出异常,如果必要的话,可以作为另一种类型的异常。 - BalusCtry
块!!!然后再使用“执行环绕”惯用语。 - Tom Hawtin - tackline除非您手动管理资源池(处理自己的内存),否则无需将输入流置空。理想情况下,您所在的任何函数都很小,并且随着对象超出范围,对该对象的引用也会消失,从而标记它进行垃圾回收。
我提到池化资源,因为如果您不加思考地关闭流而不将对象置空,则可能会意外保留您实际上不需要的对象引用。