我正在使用旧代码,它将打开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()
的结尾处关闭了?
答案 0 :(得分:7)
新实例仅由... new
(*)创建。如果您没有在此处看到new
,则说明没有创建新实例。
因此,返回不会创建任何新实例。如果没有发生getStream
中的“执行某些操作”中引发异常的情况,那么您将以一种可能的适当方式关闭它。
更好的方法是使用try-with-resources,它在保留异常方面做得更彻底。
(*)好吧,是的,在某些特定情况下,这不太正确,例如字符串连接。字符串串联和自动装箱。字符串连接,自动装箱和数组声明。我会再来的。
但是实际上,缺少new
是语法糖:在某个地方,正在调用new
。
答案 1 :(得分:0)
具有引用类型的变量仅保留对基础值的引用。您可以将其视为指针。在方法之间传递引用总是只传递引用。
因此,回答您的问题后,您的信息流已正确关闭。