Java-'throws'子句中没有从主体抛出的异常

时间:2018-08-17 05:18:13

标签: java exception

我有一个像下面这样的课程:

public class MyClass {

    public void foo() throws IOException {
        System.out.println("Hola");
    }

    public MyClass() throws IOException {

    }

}

如您所见,我在方法和构造函数的IOException子句中声明了throws。但是我不会在身体的任何地方抛出该异常。因此,它应该是编译时错误,就像我们尝试捕获未从try块引发的异常时一样。但是在这种情况下,它可以编译。谁能解释这种现象背后的原因?

3 个答案:

答案 0 :(得分:1)

声明throws IOException并不需要您实际抛出异常。

如果是这样,那么将不可能编程,因为将要求方法的所有分支都引发异常(即使在非异常情况下)。

这更多是具有完整合同的问题,在该合同中,调用方可以处理可能的异常。这适应了将来可能被迫实际引发异常的实现。
可能是出于相同的原因,允许重写的方法省略检查的异常(不会被强行强制抛出)。

答案 1 :(得分:0)

Show Stopper有一个不错的答案,并引用了一个不错的帖子。这个答案是为了帮助OP了解什么是检查和未检查的异常。

检查的异常是签名中声明的异常(无论是否引发)。

public void doSomething() throws SomeExtremelyDevastatingEndOfTheWorldException {
    // Maybe it might happen (but whoever calls this MUST acknowledge handle this case)
}

该应用程序将无法编译,因为作者认为必须处理此案才能运行该应用程序。

未检查的异常是不一定需要处理且可以在运行时冒泡的异常。

public void doSomething() {
    throws RuntimeException("not the end of the world...but we'll probably want this stacktrace and let the program run on");
}

现在,如果作者希望任何异常都可以成为未经检查的异常。

答案 2 :(得分:-1)

声明引发IOException不需要该方法引发异常。

它是方法签名和设计软件的一部分。考虑下面的例子。接口中有一种方法,它有两种实现。无论是否引发异常,这两种实现都应具有相同的签名。他们可以忽略异常子句。因此,这是编译器在编译时无法显示错误的正当理由。

Interface parent { 
    void method() throws Exception
}


Class Implementation1 {
    void method() throws Exception {
        System.out.println("Do not throws exception");
    }
}

Class Implementation2 {
    void method() throws Exception {
        throw new Exception("Error");
    }
}