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方法抛出异常会发生什么。
答案 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的关闭方法是来自overriden的Closeable,因此您只需要捕获IOException或将其添加到throws子句。
进一步AutoCloseable#close个州的javadoc
虽然声明此接口方法抛出Exception,但强烈建议实现者声明close方法的具体实现以抛出更多特定异常,或者如果close操作不能失败则不抛出任何异常。
答案 4 :(得分:0)
你需要有一个catch块,然后尝试printFileJava7()方法。如果你不想在这里捕获它,你需要在调用方法printFileJava7()的方法中处理它。我们必须捕获其中一个层,否则它将传播回调用客户端。