谁在 close 方法中捕获异常?(try-with-resources)
Posted
技术标签:
【中文标题】谁在 close 方法中捕获异常?(try-with-resources)【英文标题】:Who catch exception, arise in close method?(try-with-resources) 【发布时间】:2014-07-13 09:39:36 【问题描述】:接口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 方法抛出异常会发生什么。
【问题讨论】:
【参考方案1】:Java 在 try-with-resources 块中捕获并抑制 close 方法抛出的异常。
您可以在此处阅读有关此内容的更多信息,尤其是第二个代码示例之后的段落。 http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
【讨论】:
我认为这就是 OP 正在寻找的。 +1。我从您正在链接的文档中添加了一个引号,这样如果 OP 想要检索被抑制的异常知道该怎么做:You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.
【参考方案2】:
AutoClosable
中定义的 close()
方法抛出异常是对的。然而,扩展 AutoClosable
的其他名为 Closable
的接口重新定义了此方法,如下所示:
void close() throws IOException
所有 IO 相关的类都实现了Closable
,所以它们的close()
方法会抛出IOException
。但是您的方法也会抛出它,因此在您的代码中没有人会捕获此异常。与往常一样,如果之前没有人捕获它,它将被应用程序的上层或 JVM 本身捕获。
【讨论】:
但是否会在我的方法中捕获 IOException?我会在 cloase 方法中捕获异常抛出吗?【参考方案3】:来自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 的关闭方法是来自Closeable 的overriden,因此您只需捕获IOException 或添加它to throws 子句。
进一步了解 AutoCloseable#close 状态的 javadocs
虽然此接口方法被声明为抛出异常,但强烈建议实现者声明关闭方法的具体实现以抛出更具体的异常,或者如果关闭操作不会失败,则根本不抛出异常。
【讨论】:
【参考方案4】:这个特定场景的关键是“被抑制的异常”。
"每当体内抛出异常,然后跟随 通过 try-with-resources 语句抛出的异常,只有 在 try 的主体中抛出的异常有资格被捕获 异常处理代码。所有其他异常都被视为被抑制的异常”
Java 7 中的新概念。因此,您将获得与仅 printfileJava7 类引发异常时相同的输出,因为 close() 方法引发的 CloseException 将被抑制。
请参考When two exceptions are thrown by the try-with-resources construct链接。您所问的具体情况是什么
【讨论】:
【参考方案5】:您需要在方法 printFileJava7() 中有一个 catch 块,然后是 try。如果你不想在这里捕获它,你需要在调用方法 printFileJava7() 的方法中处理它。我们必须捕获其中一层,否则它将被传播回调用客户端。
【讨论】:
以上是关于谁在 close 方法中捕获异常?(try-with-resources)的主要内容,如果未能解决你的问题,请参考以下文章
如何在try-with-resource语句中捕获close方法引发的异常
Try-with-resources:我必须抛出或捕获 close() 方法的异常吗? [复制]