为什么在Java7中,即使永远不会抛出IOException,也可以捕获IOException
主课呢为什么在Java7中,即使永远不会抛出IOException,也可以捕获IOException,java,exception,exception-handling,try-with-resources,Java,Exception,Exception Handling,Try With Resources,主课呢 public class SampleCloseable implements AutoCloseable { private String name; public SampleCloseable(String name){ this.name = name; } @Override public void close() throws Exception { System.out.println("clos
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);
}
}
但是当我删除SampleCloseable中close()方法上的抛出异常时
我收到一个编译器错误,说IOException从未在相应的try块中抛出。因为您正在抛出一个泛型异常。由于IOException继承自Exception,因此它可能由close()方法引发。调用方不知道它实际上没有被抛出。它只看到表示可以的方法签名
实际上,close()方法可以自由抛出任何类型的异常。当然,这是一种糟糕的做法,您应该指定要抛出的特定异常。您的困惑可能是,在Java 7中,
close
方法抛出的异常被抛出到try块中,因此catch块也必须捕获它
您的close
方法被声明为引发异常,因此您的catch
块必须捕捉该异常,或者该方法必须被声明为引发Exception
由于IOException
是Exception
的一个子类,当然,您也可以尝试捕获它,只要您还捕获/声明Exception
本身
见:
给出了扩展的try with resources语句[…]的含义
通过以下转换为基本的try with resources语句
(§14.20.3.1)嵌套在try-catch或try-finally或
尝试catch finally语句
您的代码被有效地翻译为以下内容。虽然有点长,但从下面可以清楚地看到代码中发生了什么
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");
}
}
}
为什么不应该呢?你是老板。你可以决定做什么,即使这很愚蠢。IOException扩展了Exception编译器不知道IOException永远不会被抛出。你也是。
public static void main(String args[]) {
try {
Throwable primaryEx = null ;
SampleCloseable sampleCloseable = new SampleCloseable("test1")
try {
System.out.println("im in a try block");
} catch (Throwable t) {
primaryEx = t;
throw t;
} finally {
if (sampleCloseable != null) {
if (primaryEx != null) {
try {
sampleCloseable.close();
} catch (Throwable suppressedExc) {
primaryEx.addSuppressed(suppressedExc);
}
} else {
sampleCloseable.close();
}
}
} catch (IOException e) {
System.out.println("IOException is never thrown");
} catch (Exception e) {
} finally{
System.out.println("finally");
}
}