Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behaviour of try-with-resources with closable parameters

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.

like image 565
Andrew White Avatar asked Jan 31 '14 16:01

Andrew White


2 Answers

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.

like image 73
Tavian Barnes Avatar answered Sep 22 '22 03:09

Tavian Barnes


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.

like image 44
TwoThe Avatar answered Sep 23 '22 03:09

TwoThe