使用main方法检查异常处理

时间:2017-05-02 12:46:26

标签: java

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()。这是什么这个的主要原因是什么?

6 个答案:

答案 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调用m2m1也可能会抛出该异常 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 ,情况并非如此。

JLS : 11.2. Compile-Time Checking of Exceptions

中的更多信息