public class SampleCloseable implements AutoCloseable {
private String name;
public SampleCloseable(String name){
this.name = name;
}
@Override
public void close() throws Exception {
System.out.println("closing: " + this.name);
}
}
和主要课程
public class Main{
public static void main(String args[]) {
try(SampleCloseable sampleCloseable = new SampleCloseable("test1")){
System.out.println("im in a try block");
} catch (IOException e) {
System.out.println("IOException is never thrown");
} catch (Exception e) {
} finally{
System.out.println("finally");
}
}
}
但是当我在SampleCloseable里面的close()方法中删除了throws异常 我收到一个编译错误,说IOException永远不会在相应的try块中抛出。
答案 0 :(得分:10)
因为你抛出了一般的异常。由于IOException继承自Exception,因此close()方法可能会抛出它。调用者不知道它实际上没有被抛出。它只能看到方法签名,表明它可以。
实际上,close()方法可以自由地抛出任何类型的异常。当然这是不好的做法,你应该指定你正在抛出的具体例外。
答案 1 :(得分:1)
你的困惑可能就是在Java 7中,从[{1}}方法抛出的[声明]异常被抛出在 try块中,所以你的捕获块也必须抓住它。
您的close
方法被声明为抛出异常,因此您的close
块必须捕获它,或者必须声明方法抛出catch
。
由于Exception
是IOException
的子类,因此您当然也可以尝试捕获它,只要您同时捕获/声明Exception
本身。
请参阅JLS 14.20.3.2:
给出了扩展的try-with-resources语句的含义[...] 通过以下翻译到基本的try-with-resources语句 (§14.20.3.1)嵌套在try-catch或try-finally或 try-catch-finally statement。
您的代码有效地转换为以下内容。虽然有点长,但从下面应该清楚你的代码中发生了什么。
Exception