0

接口AutoClosable有以下方法声明:

void close()  throws Exception

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

当我编写代码尝试使用资源时,它看起来像这样:

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 方法抛出异常会发生什么。

4

5 回答 5

2

Java 捕获并抑制由 try-with-resources 块中的 close 方法引发的异常。

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

于 2014-07-13T09:43:42.740 回答
0

这种特殊情况的关键是“被抑制的异常”。

“每当在主体内抛出异常,然后由 try-with-resources 语句引发异常时,只有在 try 的主体中抛出的异常才有资格被异常处理代码捕获。所有其他异常被认为是被抑制的异常”

Java 7 的一个新概念。因此,您将获得与仅 printfileJava7 类引发异常时相同的输出,因为 close() 方法引发的 CloseException 将被抑制。

请参阅当 try-with-resources 构造链接引发两个异常时。这已经采取了您所问的确切情况

于 2014-07-13T09:44:58.923 回答
0

你是对的,在throws 异常中close()定义的方法。AutoClosable然而Closable,其他名为 extends的接口AutoClosable重新定义了这个方法,如下所示:

void close() throws IOException

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

于 2014-07-13T09:45:30.727 回答
0

来自关于异常的编译时检查的 jls

当涉及接口时,一个以上的方法声明可能会被一个覆盖声明覆盖。在这种情况下,覆盖声明必须具有与所有覆盖声明兼容的 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的 close 方法被Closeable覆盖,因此您只需捕获IOException或将其添加到 throws 子句。

进一步AutoCloseable#close状态的javadocs

虽然此接口方法被声明为抛出异常,但强烈建议实现者声明 close 方法的具体实现以抛出更具体的异常,或者如果关闭操作不会失败,则根本不抛出异常。

于 2014-07-13T10:26:50.987 回答
0

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

于 2016-01-27T22:53:46.570 回答