为什么在java 7中可以捕获IOException,即使永远不会抛出IOException

时间:2014-12-21 02:34:21

标签: 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("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块中抛出。

2 个答案:

答案 0 :(得分:10)

因为你抛出了一般的异常。由于IOException继承自Exception,因此close()方法可能会抛出它。调用者不知道它实际上没有被抛出。它只能看到方法签名,表明它可以。

实际上,close()方法可以自由地抛出任何类型的异常。当然这是不好的做法,你应该指定你正在抛出的具体例外。

答案 1 :(得分:1)

你的困惑可能就是在Java 7中,从[{1}}方法抛出的[声明]异常被抛出 try块中,所以你的捕获块也必须抓住它。

您的close方法被声明为抛出异常,因此您的close块必须捕获它,或者必须声明方法抛出catch

由于ExceptionIOException的子类,因此您当然也可以尝试捕获它,只要您同时捕获/声明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