流可以通过返回的方法关闭吗?

时间:2018-12-17 20:07:30

标签: java stream resources

我正在使用旧代码,它将打开InputStream到文件,并且我很好奇流是否被正确关闭。我们目前拥有的方法是返回一个InputStream,该InputStream由一个单独的方法调用,该方法随后将其关闭:

public void doThing(String path) throws Exception {

   InputStream is = getStream(path);

   try {
       ...   // Do some stuff
   } finally {
       if(is != null)
           is.close();
   }
}

public InputStream getStream(String path) throws Exception {

    InputStream is = new FileInputStream(new File(path));
    ...     // Do some stuff
    return is;
}

但是我不确定对doThing()的调用是否可以正确关闭InputStream is的所有实例。我知道在doThing()方法中,InputStream的实例由getStream()返回,并由finally块正确关闭。那部分很清楚。

我不确定的是getStream()方法是否产生了InputStream的一个新实例,该实例未正确关闭。

也就是说,当getStream()返回时,是返回对原始对象is引用,还是返回新实例 is中的值相同?

如果是前者,那么我有信心doThing()方法将关闭所有Streams到文件。如果是后者,那么我担心我可能创建了另一个从未显式关闭的流。取而代之的是,垃圾收集器只会将该对象标记为删除,而垃圾收集器最终可能会也可能不会删除它。我想避免这种情况。

is的所有实例是否在doThing()的结尾处关闭了?

2 个答案:

答案 0 :(得分:7)

新实例仅由... new(*)创建。如果您没有在此处看到new,则说明没有创建新实例。

因此,返回不会创建任何新实例。如果没有发生getStream中的“执行某些操作”中引发异常的情况,那么您将以一种可能的适当方式关闭它。

更好的方法是使用try-with-resources,它在保留异常方面做得更彻底。


(*)好吧,是的,在某些特定情况下,这不太正确,例如字符串连接。字符串串联和自动装箱。字符串连接,自动装箱和数组声明。我会再来的。

但是实际上,缺少new是语法糖:在某个地方,正在调用new

答案 1 :(得分:0)

具有引用类型的变量仅保留对基础值的引用。您可以将其视为指针。在方法之间传递引用总是只传递引用。

因此,回答您的问题后,您的信息流已正确关闭。