Can Streams be closed by the method they return to?

Lord Farquaad :

I'm working with legacy code which opens an InputStream to a file, and I'm curious if the stream is being closed properly. What we currently have is a method which returns an InputStream invoked by a separate method which later closes it:

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;
}

But I'm not certain if a call to doThing() properly closes all instances of the InputStream is. I understand that within the doThing() method, an instance of the InputStream is returned by getStream(), and is properly closed by the finally block. That part's clear.

What I'm not certain of is whether or not the getStream() method spawns a new instance of the InputStream which is not properly closed.

That is, when getStream() returns, is it returning a reference to the original object is, or is it returning a new instance of is with the same value?

If it's the former, then I'm confident that the doThing() method will have closed any and all Streams to the file. If it's the latter though, then I'm concerned I may have created another stream which is never explicitly closed. Instead, the object would just be marked for deletion by the Garbage Collector which may or may not eventually get rid of it. I'd like to avoid that.

Are all instances of is closed at the end of doThing()?

Andy Turner :

New instances are only created by... new (*). If you don't see a new there, there isn't a new instance being created.

So, no new instance is created by the return. Provided nothing happens that throws an exception in the "do some stuff" in getStream, you are closing this in a likely adequate way.

A better way would use try-with-resources, which does a more thorough job of preserving exceptions.


(*) Ok, yes, there are some specific cases where this isn't quite true, for example string concatenation. String concatenation and autoboxing. String concatenation, autoboxing and array declaration. I'll come in again.

But actually, the lack of new is syntactic sugar: somewhere, a new is being invoked.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=87992&siteId=1