Java - “抛出”子句中的异常未从主体中抛出

问题描述 投票:0回答:4

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

public class MyClass {

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

    public MyClass() throws IOException {

    }

}

如您所见,我在方法和构造函数的

IOException
子句中声明
throws
。但我不会在身体的任何地方抛出这个异常。所以它应该是一个编译时错误就像当我们尝试捕获不是从 try 块抛出的异常时。但在这种情况下它编译得很好。谁能解释一下这种行为背后的原因吗?

java exception
4个回答
1
投票

声明

throws IOException
并不要求您实际抛出异常。

如果是这样的话,那么就不可能编程,因为该方法的所有分支都需要抛出异常(即使在非异常情况下)。

这更多的是一个拥有完整合约的问题,其中调用者能够处理可能的异常。这适应了未来可能被迫实际抛出异常的实现。
可能出于同样的原因,允许重写的方法省略已检查的异常(您不会被迫抛出它)


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");
}

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


0
投票

你是对的。这是该语言中的一个合法错误。我会给出一个原因。假设我正在编写一个

delete
方法,该方法应该删除文档。如果文档不存在,我想抛出异常(我不想默默地失败),所以我写了这个方法:

public void delete() throws DocumentNotFoundException

如果我忘记在文档不存在时抛出异常,则该错误将不会被捕获。正如你所说:

所以这应该是一个编译时错误,就像我们尝试捕获未从 try 块中抛出的异常一样。

如果声明抛出受检查异常但从未在方法中抛出,则正确的编译器行为是引发错误。这将帮助程序员捕获代码中的错误。


-1
投票

声明 throws 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");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.