Question

Does Java-7's try-with-resources require the closable to be assigned directly to a variable? In short, is this block of code...

    try (final ObjectInputStream ois = new ObjectInputStream(
            new ByteArrayInputStream(data))) {
        return ois.readObject();
    }

Equivalent to this block?...

    try (final ByteArrayInputStream in = new ByteArrayInputStream(data);
         final ObjectInputStream ois = new ObjectInputStream(in)) {
        return ois.readObject();
    }

My understanding of Section 14.20.3 of the Java Language Specification says they are not the same and the resources must be assigned. This would be surprising from a common usage standpoint and I can't find any documentation warning against the pattern.

Was it helpful?

Solution

The two blocks are not equivalent in the sense that they won't generate the same code. But since ObjectInputStream.close() will call close() on the ByteArrayInputStream that you passed it, the first block is completely fine.

EDIT: Something I forgot is that unlike reasonable constructions like new BufferedInputStream(new *InputStream(...)), the ObjectInputStream constructor actually reads from the stream you pass it and thus could reasonably throw an exception. For that reason I'd actually recommend the second block, not the first block.

OTHER TIPS

The code is not the same as you already mentioned, as Java will generate a close block for each variable even though it is not necessary. What is more important is this comment from the JavaDocs on AutoCloseable:

Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.

Basically it means that calling close() twice should not have any effect, but it is not guaranteed. So it is recommended to avoid the 2nd construct you presented to avoid calling close twice.

Always use the second form. In the first form "new ObjectInputStream()" will throw an exception if the array is empty. This will leave the ByteArrayInputStream open.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top