尝试使用资源:我必须抛出或捕获close()方法的异常吗?

Joh*_*ick 42 java exception-handling

如果这是错误的,请纠正我:在Java 7的try-with-resources语句中,资源close()方法抛出的任何异常都必须声明为我的方法抛出,或者我必须将整个try包装在另一个try捕获由异常引发的异常中close().

如果是这样,我不得不怀疑我是否会充分利用它.我当然不希望throw抛出异常close(),调用者不知道该怎么做.至少对我来说,try另一个try只是处理它的包装close()看起来不会很优雅.

编辑: 我想我不小心问了两个问题,其中一个是重复的.

问题1.我是否必须声明我的方法从方法中抛出异常close()或在另一次尝试中包装try-with-resources?(未在建议的副本中回答.)

问题2.有没有办法静默关闭资源?(显然是重复的,所以我不接受这个句子.希望这使得这个问题令人满意地独特.)

def*_*ale 34

引用Java语言规范($ 14.20.3.2):

14.20.3.2扩展试用资源

试,与资源语句至少一个catch子句和/或finally子句称为扩展的尝试,与资源的语句.扩展的try-with-resources语句的含义:

    尝试ResourceSpecification
        Block
    Catches opt
    最后选择

通过以下转换给出嵌套在try-catchtry-finallytry-catch-finally 语句中的基本 try-with-resources语句(§14.20.3.1) :

    尝试{
        尝试ResourceSpecification
            Block
    }
    捕获选择
    最后选择

翻译的效果是将ResourceSpecification置于try语句的"内部".这允许扩展的try-with-resources语句的catch子句捕获由于自动初始化或关闭任何资源而导致的异常.

所以,基本上,包装器已经实现了


JB *_*zet 23

来自Java教程

try-with-resources语句可以像普通的try语句一样有catch和finally块.在try-with-resources语句中,在声明的资源关闭后运行任何catch或finally块.

(强调我的)

所以你可以做到

try (BufferedReader br =
               new BufferedReader(new FileReader(path))) {
    return br.readLine();
}
catch (IOException e) {
    // handle the exception that has been thrown by readLine() OR by close().
}
Run Code Online (Sandbox Code Playgroud)

  • 如果资源不调用 catch 并且没有 finally 块,它会被关闭吗? (2认同)
  • 这种方法并不能解决问题。对我来说,“正常”行为是:1) 从 readLine 重新抛出异常 2) 忽略 close 抛出的异常。按照您建议的方式进行操作,没有一种简单的方法可以知道异常是来自 readLine 还是来自 close。 (2认同)

Per*_*ion 7

您不需要在另一个try-catch块中包装try-with-resources,只需添加一个catch块:

class Foo implements AutoCloseable {
    public void close() throws Exception {
        throw new Exception();
    }
}

public class Try {
    public static void main(final String[] args) {
        try(Foo f = new Foo()) {
            System.out.println("No op!");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)