不需要抛出异常就可以被捕获,但是IOException会这样做

时间:2017-12-18 04:47:38

标签: java exception throws

为什么以下代码编译正常,但被调用的方法不需要抛出Exception?不是Exception已检查的异常,而不是未经检查的异常吗?请澄清。

class App {
    public static void main(String[] args) {
        try {
            amethod();
            System.out.println("try ");
        } catch (Exception e) {
            System.out.print("catch ");
        } finally {
            System.out.print("finally ");
        }
        System.out.print("out ");
    }
    public static void amethod() { }
}

如果我想使用带有IOexception的try catch(已检查的异常),则被调用的方法需要抛出IOException。我明白了。

import java.io.IOException;

class App {
    public static void main(String[] args) {
        try {
            amethod();
            System.out.println("try ");
        } catch (IOException e) {
            System.out.print("catch ");
        } finally {
            System.out.print("finally ");
        }
        System.out.print("out ");
    }
    public static void amethod() throws IOException { }
}

2 个答案:

答案 0 :(得分:1)

Isn't 'Exception' a checked exception and not an unchecked exception?

Yes, it is.

But even if we know the method doesn't throw Exception itself, the code catch(Exception e){ could still execute. The code in the try block could still throw something that inherits from Exception. That includes RuntimeException and its subclasses, which are unchecked.

catch(IOException e){, on the other hand, can only catch checked exceptions. (Java doesn't allow multiple inheritance, so anything that's a subclass of IOException can't possibly be a subclass of RuntimeException.) The compiler can fairly easily figure out that none of the code in the try block can possibly throw an IOException (since any method throwing a checked exception must explicitly say so) which allows it to flag the code.

答案 1 :(得分:1)

The behavior you're observing comes from the fact that the Java Language Specification treats Exception specially in this circumstance. According to §11.2.3:

It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, unless E1 is Exception or a superclass of Exception.

This is reasonable because Exception (and its superclass Throwable) can be used to catch exceptions that extend RuntimeException also. Since runtime exceptions are always possible, the compiler always allows Exception to appear in a catch clause regardless of the presence of checked exceptions.