谁捕获异常,以密切方式出现?(尝试使用资源)

时间:2014-07-13 09:39:37

标签: java exception exception-handling try-with-resources

interface AutoClosable具有以下方法声明:

void close()  throws Exception

因此我们看到close方法可以抛出Exception。

当我编写代码try-with资源时,它看起来像这样:

private static void printFileJava7() throws IOException {

    try(FileInputStream input = new FileInputStream("file.txt")) {

        int data = input.read();
        while(data != -1){
            System.out.print((char) data);
            data = input.read();
        }
    }
}

此代码缺少异常处理。

我不明白如果close方法抛出异常会发生什么。

5 个答案:

答案 0 :(得分:2)

Java捕获并抑制try-with-resources块中close方法抛出的异常。

您可以在此处阅读更多相关信息,特别是第二个代码示例后的段落。 http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

答案 1 :(得分:0)

此特定情况的关键是"压缩异常"。

  

"每当在体内抛出异常,然后跟随   通过try-with-resources语句抛出的异常,只有   在try的正文中抛出的异常有资格被捕获   异常处理代码。所有其他例外都被视为被拒绝的例外情况"

Java 7.SO的新概念,只有printfileJava7类抛出异常时才会得到相同的输出,因为close()方法抛出的CloseException将被抑制。

请参阅When two exceptions are thrown by the try-with-resources construct链接。哪些确切地说明了您的要求

答案 2 :(得分:0)

close()中定义的AutoClosable方法抛出异常是对的。但是,扩展Closable的其他名为AutoClosable的接口重新定义了此方法,如下所示:

void close() throws IOException

所有与IO相关的类都实现Closable,因此他们的close()方法会抛出IOException。但是你的方法也抛出它,所以在你的代码中没有人捕获这个异常。一如既往,它将被应用程序的上层或JVM本身捕获,如果之前没有人捕获它的话。

答案 3 :(得分:0)

来自jls about Compile-Time Checking of Exceptions

  

当涉及接口时,单个覆盖声明可以覆盖多个方法声明。在这种情况下,重写声明必须具有与所有重写声明兼容的throws子句(第9.4.1节)。

所以当你有像

这样的东西时
static class AC implements AutoCloseable {
    @Override
    public void close() throws Exception {
        throw new Exception("btooom!");
    }
    public void ac() {
        System.out.println("no");
    }
}

public static void main(String[] args) throws Exception {
    try(AC ac = new AC()) {
        ac.ac();
    }
}

然后你被要求向周围的try块添加一个catch子句或者添加一个throws声明。

如果是FileInputStream并且要应用jsl声明的内容,那么AutoCloseable的关闭方法是来自overridenCloseable,因此您只需要捕获IOException或将其添加到throws子句。

进一步AutoCloseable#close个州的javadoc

  

虽然声明此接口方法抛出Exception,但强烈建议实现者声明close方法的具体实现以抛出更多特定异常,或者如果close操作不能失败则不抛出任何异常。

答案 4 :(得分:0)

你需要有一个catch块,然后尝试printFileJava7()方法。如果你不想在这里捕获它,你需要在调用方法printFileJava7()的方法中处理它。我们必须捕获其中一个层,否则它将传播回调用客户端。