请问InputStreams和OutputStreams在破坏Java的close()方法? 我完全理解,这可能是不好的形式(尤指C和C ++的世界),但我很好奇。
此外,假设我有以下代码:
private void foo()
{
final string file = "bar.txt";
Properties p = new Properties();
p.load( new FileInputStream(file) );
//...
}
是否无名的FileInputStream超出范围p.load()之后,因此被摧毁,有点像C ++作用域规则? 我试图寻找对谷歌的Java匿名变量的作用域,但没来什么,我认为这将是。
谢谢。
第一个答案:在Java中有作为“毁灭”没有这样的事情(在C ++的观点)。 只有有垃圾收集,这可能会或可能不会醒来,当它看到一个对象,准备好要收集完成其工作。 GC在Java中通常是不值得信任的。
第二个答案:有时候有,有时候没有,但不值得冒险了。 从Elliote Rusty Harold的Java的IO :
并非所有的数据流需要被封闭的字节数组输出流并不需要被关闭,例如。 然而,与流当你与他们进行文件和网络连接应该始终被关闭有关。 例如,如果你打开一个文件进行写入和忽视关闭它,当你通过,那么其他进程可读取或写入到该文件受阻。
根据哈罗德,同样也适用于输入或输出流。 也有一些例外(他指出System.in),但在一般情况下,你承担风险,如果你当你做不关闭文件流。 并关闭他们在一个finally块,以确保他们得到即使抛出一个异常关闭。
我曾经设想流将通过垃圾收集自动最终被关闭,但传闻证据表明,如果不手动关闭它们导致资源泄漏。 你会希望做这样的事情,而不是:
InputStream stream = null;
try {
stream = new FileInputStream("bar.txt");
Properties p = new Properties();
p.load(stream);
}
catch(Exception e) {
// error handling
}
finally {
closeQuietly(stream);
}
closeQuietly()
是一个方法IOUtils
Apache的公地IO库。
不,有在Java中没有析构函数。 可以存在于对象其他参考文献,即使经过给它的一个特定参考超出范围(或修改)。 如果对象不再可达,流可以有一个名为其finaliser晚些时候将关闭流。
Properties.load
的特别之处在它关闭传递给它的流。 编辑: Properties.loadFromXML
是我似乎已经大约五年前左右想着特殊方法。 (API文档应前,而不是之后可能会说)谢谢@tzimnoch。
该变量超出范围,因此被破坏。 但在Java中,有一个变量 ,该变量指向的对象之间是有很大的区别。
指向的对象时, 变量超出范围不仅破坏。 当Java运行时引擎决定,感觉就像让周围摧毁不受任何范围变量指向的对象,该对象才销毁。
简短的回答是“也许吧,但不要指望这个!”。
某处的实现的FileInputStream类堆栈具有一类finalizer
,这将有效地关闭流(并释放资源)在运行时。
问题是,没有任何的终结将永远运行的保证。 从JLS(部分12.6)报价:
Java编程语言不指定终结将如何尽快被调用,只是说该对象的存储重用前它会发生。
这使得流定稿问题:
- 如果您的Stream对象永远不会成为垃圾,它永远不会被敲定。
- 如果您的Stream对象是终身教授,可能需要被垃圾收集和完成之前很长一段时间。
- 该JVM可能需要执行额外的GC周期执行终结前的对象被确定为不可达之后。 这当然是由JLS允许的!
- 这在技术上是合法的JVM到永远,永远执行终结,只要它永远不会重用与终结的对象存储。 (我不知道有任何产品质量的JVM是走这条线,但你永远不知道...)