具有可关闭参数的try-with-resources的行为

时间:2014-01-31 16:07:45

标签: java try-with-resources

Java-7的try-with-resources是否需要将closable直接分配给变量?简而言之,就是这段代码......

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

相当于这个区块?...

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

我对Java Language Specification第14.20.3节的理解说它们不一样,必须分配资源。从常见的使用角度来看,这将是令人惊讶的,我找不到任何针对该模式的文档警告。

3 个答案:

答案 0 :(得分:4)

这两个块在它们不会生成相同代码的意义上不相同。但由于ObjectInputStream.close()会在您传递的close()上调用ByteArrayInputStream,因此第一个块完全正常。

编辑:我遗忘的是,与new BufferedInputStream(new *InputStream(...))之类的合理构造不同,ObjectInputStream构造函数实际上从您传递的流中读取,因此可以合理地抛出异常。出于这个原因,我实际上推荐第二个块,而不是第一个块。

答案 1 :(得分:2)

代码与您已经提到的代码不同,因为Java会为每个变量生成一个关闭块,即使它不是必需的。更重要的是来自AutoCloseable上的JavaDocs的评论:

  

请注意,与Closeable的close方法不同,此close方法是   不要求是幂等的。换句话说,称之为接近   方法不止一次可能有一些可见的副作用,不像   Closeable.close,如果调用更多,则无效   不止一次。但是,这个界面的实施者是强烈的   鼓励他们的近似方法是幂等的。

基本上这意味着调用close()两次 应该没有任何效果,但不能保证。所以建议避免你提出的第二个构造,以避免两次调用。

答案 2 :(得分:0)

始终使用第二种形式。在第一种形式中,“new ObjectInputStream()”将在数组为空时抛出异常。这将离开 ByteArrayInputStream打开。