Should an OutputStream object (created as an expression in method call, but not assigned to a variable) still be closed?

fileoutputstream, garbage-collection, java

Solution

That's not an anonymous object (or rather an anonymous class). It's just an unassigned object instantiation.

Once you create it and pass it to `store` there is a reference to it, therefore it is not GC'd. Once `store` returns that reference disappears, but you should still track the variable and dispose of it after `store` returns. It is safer to just to treat all resources in the same standard way and call `close` when you are done with them, this helps avoid a lot of resource leak errors when some `finalize` methods call `close` ad other's don't, and also avoids issues due to non-deterministic GC.

You also don't know what may change in a finalizer implementation in a future version so always calling `close` is best practice.

A try-with-resources block (Java Tutorials > The try-with-resources statement) is ideal for this:

Properties p = new Properties();

try (FileOutputStream stm = new FileOutputStream("nameOfFile"))
{
    p.store(stm, "Created by me.");     
} catch (IOException e) {
    // TODO: handle this
}

That block, when used with any (and potentially multiple) `Autocloseable`, will call `close` at the end and nicely handle things like exceptions on `close` or exceptions in the body and on `close` as well. If both the body and `close` throw exceptions then the body exception is rethrown and the `close` exception is available through `e.getSuppressed()`.

You should not call `Autocloseable.close()` yourself if you use one of these blocks as that method is not indempotent - calling it twice may have side effects the second time. If you have a `Closeable` then you are safe to call it multiple times. From the docs:

Note that unlike the close method of Closeable, this close method is not required to be idempotent

In Java 6 or less you have to do your own exception handling statement which is hard as you have to handle the case where both your body, and the `close` both throw exceptions.

Problem

I'm trying to use a FileOutputStream anonymously for storing a property with java.util.Property's store method. ``` Properties p = new Properties(); . . . p.store(new FileOutputStream("nameOfFile"), "Created by me."); ``` Reading the javadocs for the store method it says that the stream will be flushed and remain open after the method returns. I'm wondering what happens with the stream. Since I've instantiated it anonymously I'm under the assumption that the object will be garbage collected immediately (if that is wrong, please correct me). However, I was taught to always close my streams when I'm finished with them. In this case, I am unable to close the stream since I have no object referring to it. Do I need to be worried about the stream being left open here, or does Java take care of it appropriately in this case by immediately collecting the object?

Original source