我有一个像下面这样的课程:
public class MyClass {
public void foo() throws IOException {
System.out.println("Hola");
}
public MyClass() throws IOException {
}
}
如您所见,我在方法和构造函数的IOException
子句中声明了throws
。但是我不会在身体的任何地方抛出该异常。因此,它应该是编译时错误,就像我们尝试捕获未从try块引发的异常时一样。但是在这种情况下,它可以编译。谁能解释这种现象背后的原因?
答案 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");
}
}