我试图匿名使用FileOutputStream来存储带有java.util.Property存储方法的属性。
Properties p = new Properties();
. . .
p.store(new FileOutputStream("nameOfFile"), "Created by me.");
读取store方法的javadoc,它表示流将被刷新并在方法返回后保持打开状态。
我想知道流会发生什么。由于我是匿名实例化的,我假设对象将立即被垃圾收集(如果这是错误的,请纠正我)。然而,当我完成它们时,我被教导要始终关闭我的溪流。在这种情况下,我无法关闭流,因为我没有对象引用它。我是否需要担心流在这里打开,或者在这种情况下Java是否通过立即收集对象来适当地处理它?</ p>
答案 0 :(得分:4)
这不是匿名对象(或者更确切地说是匿名类)。它只是一个未分配的对象实例化。
创建它并将其传递给store
之后会有一个对它的引用,因此它不是GC'd。一旦store
返回该引用消失,但您仍应跟踪该变量并在store
返回后将其丢弃。只需以相同的标准方式处理所有资源并在完成后调用close
更安全,这有助于在某些finalize
方法调用{{1}时避免大量资源泄漏错误其他人不这样做,也避免了由于非确定性GC引起的问题。
您还不知道未来版本中的终结器实现可能会发生什么变化,因此始终调用close
是最佳做法。
try-with-resources块(Java Tutorials > The try-with-resources statement)非常适用于此:
close
该块与任何(可能是多个)Properties p = new Properties();
try (FileOutputStream stm = new FileOutputStream("nameOfFile"))
{
p.store(stm, "Created by me.");
} catch (IOException e) {
// TODO: handle this
}
一起使用时,会在最后调用Autocloseable
并很好地处理close
上的异常或正文和异常中的异常close
也是如此。如果正文和close
抛出异常,则会重新抛出正文异常,close
可以通过close
获得异常。
如果您使用其中一个块,则不应自己调用Autocloseable.close()
,因为该方法不是无效的 - 调用它两次可能会产生第二次副作用。如果您有e.getSuppressed()
,那么您可以安全地多次调用它。来自文档:
请注意,与Closeable的close方法不同,此close方法不需要是幂等的
在Java 6或更低版本中,您必须执行自己的异常处理语句,这很难,因为您必须处理您的正文和Closeable
都抛出异常的情况。
答案 1 :(得分:2)
垃圾收集通常不包括开放文件或流等资源,除非finalize
方法显式关闭对象的底层资源。
检查finalize
FileOutputStream
的代码,似乎确保调用了close
:
/**
* Cleans up the connection to the file, and ensures that the
* <code>close</code> method of this file output stream is
* called when there are no more references to this stream.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/*
* Finalizer should not release the FileDescriptor if another
* stream is still using it. If the user directly invokes
* close() then the FileDescriptor is also released.
*/
runningFinalize.set(Boolean.TRUE);
try {
close();
} finally {
runningFinalize.set(Boolean.FALSE);
}
}
}
}
但是,始终手动或在try-with-resources
语句中关闭资源总是更好,因为并非所有流对象都可能在被取消引用时关闭,并且即使他们确定最终确定也不能保证按照预期发生:
try(FileOutputStream outStream = new FileOutputStream("nameOfFile")) {
Properties p = new Properties();
. . .
p.store(outStream, "Created by me.");
}
答案 2 :(得分:0)
创建一个对象......
FileOutputStream fos = new FileOutputStream("nameOfFile")
然后使用它......
p.store(fos, "Created by me.");
最后关闭它。
Properties.store()命令不保留对流的引用,因此没有对它的引用,因此在方法返回后它将是GC,因为它是流范围的范围。 / p>