public class s1 {
void m1(){
m2();
}
String m2() throws IOException{
BufferedReader inputFile = new BufferedReader(new FileReader("a.txt"));
String line = inputFile.readLine();
inputFile.close();
return line;
}
}
public class Main {
public static void main(String[] args) {
s1 obj1 = new s1();
try {
obj1.m1();
}
catch (Exception e){
System.out.println("I got it!");
}
}
}
当我运行此代码时,我得到了
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type IOException
我对这条消息感到困惑,因为我认为我在main方法中处理了这个已检查过的IOException.Yet,编译器也希望我将throws
添加到void m1()
。这是什么这个的主要原因是什么?
答案 0 :(得分:1)
m1调用的方法m2抛出异常。所以你应该:
将throws IOException
添加到方法m1
或
在try块中调用方法m2
因为必须通过m2引发的异常来完成某些事情,要么被抓住要再次被抛出。
答案 1 :(得分:0)
您的方法m1
调用另一个抛出异常的方法m2
,因此m1
必须抛出它,这就是Java的设计方式。
如果您在方法try/catch
中使用m2
来捕获该异常,则无需向其添加throws
。因此,如果您不想将throws IOException
添加到m2
以及调用m2
的所有内容 - 请在此方法中立即捕获它。
答案 2 :(得分:0)
编译器也希望我向void m1()添加throws。什么是 这个的主要原因是什么?
异常处理有两个主要方面,报告和恢复。在Java中,异常处理提供了一种灵活的机制,用于将控制从错误报告传递到补充恢复处理程序。
throws
子句向您的方法的调用方发出信号,表明它可能遇到IOException
。然后调用者需要做出相同的决定,处理异常或告诉其调用者可能抛出异常。
简单地说,如果一个方法正在使用throws
子句,那么这隐含地告诉其他方法 - “如果你打电话给我,你必须处理我抛出的这些异常”。
答案 3 :(得分:0)
方法m2
可能会抛出IOException
由于m1
调用m2
,m1
也可能会抛出该异常
IOException
并非来自RuntimeException
,因此可能会引发它可能被抛出的事实。
换句话说,将throws IOException
添加到m1
的声明中。
答案 4 :(得分:0)
任何调用抛出任何Checked异常的方法的方法都必须处理它们或抛出它们。如果没有通过捕获然后在方法的签名中处理,则必须声明异常,以便此方法的任何调用者知道要处理的异常。 Checked Exception是故意针对某些特殊情况而必须处理或抛出的。在您的情况下,m2()
会抛出checkedException和m1()
调用m2()
,因此m1()
方法的签名责任允许m1()
的任何调用者知道有必要处理特殊情况的可能性。请注意,在您的情况下,您只是从main方法调用它,但不会阻止您或任何其他开发人员在将来从任何其他方法调用它。抛出已检查异常的方法的责任是声明存在异常情况并需要处理,调用者只需处理它们。
希望您现在明白需要修改m1()
的签名并为IOException
添加缺少的声明。
答案 5 :(得分:0)
让我们看看JLS: 11.3. Run-Time Handling of an Exception 说的是什么。
当抛出异常时(第14.18节),控制从导致异常的代码转移到可以处理异常的try语句(§14.20)的最近的动态封闭catch子句(如果有的话)。
...
如果找不到可以处理异常的catch子句,则终止当前线程(遇到异常的线程)。在终止之前,将执行所有finally子句,并根据以下规则处理未捕获的异常:
以后的例子:
方法thrower的声明必须有一个throws子句,因为它可以抛出TestException的实例,这是一个经过检查的异常类(第11.1.1节)。如果省略throws子句,则会发生编译时错误。
这最后一个语句正是您的情况,m1
省略了throws子句,因此发生编译时错误。添加此{1}}或此Exception的任何超类/接口以更正此错误。
注意:
有趣的是,如果您尝试使用实际代码从throws IOException
捕获IOException
,则会在尝试捕获未填充的异常时遇到其他编译时错误。但main
不是这种情况,因为只有已检查的异常才会出现这种情况,因为Exception
只能{strong>未经检查的异常 Exception
,情况并非如此。