是否输入/ OutputStreams接近毁灭?(Does Input/OutputStreams

2019-07-21 00:30发布

请问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匿名变量的作用域,但没来什么,我认为这将是。

谢谢。

Answer 1:

第一个答案:在Java中有作为“毁灭”没有这样的事情(在C ++的观点)。 只有有垃圾收集,这可能会或可能不会醒来,当它看到一个对象,准备好要收集完成其工作。 GC在Java中通常是不值得信任的。

第二个答案:有时候有,有时候没有,但不值得冒险了。 从Elliote Rusty Harold的Java的IO

并非所有的数据流需要被封闭的字节数组输出流并不需要被关闭,例如。 然而,与流当你与他们进行文件和网络连接应该始终被关闭有关。 例如,如果你打开一个文件进行写入和忽视关闭它,当你通过,那么其他进程可读取或写入到该文件受阻。

根据哈罗德,同样也适用于输入或输出流。 也有一些例外(他指出System.in),但在一般情况下,你承担风险,如果你当你做不关闭文件流。 并关闭他们在一个finally块,以确保他们得到即使抛出一个异常关闭。



Answer 2:

我曾经设想流将通过垃圾收集自动最终被关闭,但传闻证据表明,如果不手动关闭它们导致资源泄漏。 你会希望做这样的事情,而不是:

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库。



Answer 3:

不,有在Java中没有析构函数。 可以存在于对象其他参考文献,即使经过给它的一个特定参考超出范围(或修改)。 如果对象不再可达,流可以有一个名为其finaliser晚些时候将关闭流。

Properties.load的特别之处在它关闭传递给它的流。 编辑: Properties.loadFromXML是我似乎已经大约五年前左右想着特殊方法。 (API文档应前,而不是之后可能会说)谢谢@tzimnoch。



Answer 4:

变量超出范围,因此被破坏。 但在Java中,有一个变量 ,该变量指向对象之间是有很大的区别。

指向对象时, 变量超出范围不仅破坏。 当Java运行时引擎决定,感觉就像让周围摧毁不受任何范围变量指向的对象,该对象才销毁。



Answer 5:

简短的回答是“也许吧,但不要指望这个!”。

某处的实现的FileInputStream类堆栈具有一类finalizer ,这将有效地关闭流(并释放资源)在运行时。

问题是,没有任何的终结将永远运行的保证。 从JLS(部分12.6)报价:

Java编程语言不指定终结将如何尽快被调用,只是说该对象的存储重用前它会发生。

这使得流定稿问题:

  1. 如果您的Stream对象永远不会成为垃圾,它永远不会被敲定。
  2. 如果您的Stream对象是终身教授,可能需要被垃圾收集和完成之前很长一段时间。
  3. 该JVM可能需要执行额外的GC周期执行终结前的对象被确定为不可达之后。 这当然是由JLS允许的!
  4. 这在技术上是合法的JVM到永远,永远执行终结,只要它永远不会重用与终结的对象存储。 (我不知道有任何产品质量的JVM是走这条线,但你永远不知道...)


文章来源: Does Input/OutputStreams close on destruction?
标签: java scope