2017-05-02 46 views
0
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!"); 
     } 
    } 
} 

当我运行这段代码,我从main方法的检查异常

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type IOException 

我感到困惑的是消息,因为我认为我处理这个检查IOException异常的主要方法处理。然而,编译器希望我也将throws添加到void m1()。这样做的主要原因是什么?

+1

每一个方法调用平方米必须确定它是如何HANDELS是例外。那确实包括m1。 –

+0

'm1'调用'm2','m2'抛出'IOException'。但'm1'不处理异常,因此您必须选择:make'm1'引发异常,或为'm2'调用添加'try/catch'块 –

+0

与'm2'完全相同捕获或声明抛出可能在其调用的方法中发生的'IOException'(例如'readLine()'),'m1'也必须执行相同的操作,因为它会调用一个方法('m2()') IOException'。 – Berger

回答

0

你的方法m1调用另一个方法m2它抛出异常,所以m1必须抛出它,这就是Java的设计。

如果您在方法m2中使用try/catch来捕获该异常,则不需要向其中添加throws。因此,如果您不想将throws IOException添加到m2以及所有调用m2的内容,请立即在此方法中抓取它。

1

由m1调用的方法m2引发异常。所以,你应该:

添加throws IOException于方法M1

呼叫try块里面的方法M2

因为有些事情必须与M2抛出的异常做了,无论是被抓住再被抛出。

0

编译器希望我将void抛出也添加到void m1()中。 这是什么主要原因?

有异常处理的两个主要方面,报告恢复。在Java异常处理中提供了一种灵活的机制,用于将控制从错误点报告传递到补充恢复处理程序。

throws子句向您的方法的调用者发出信号,表示它可能会遇到IOException。然后,调用者需要做出与相同的决定,处理该异常或告诉其调用者该异常可能被抛出。

简单地说,如果一个方法是使用throws条款那么这个隐含告诉其他方法 - “如果你给我打电话,你必须处理这些异常,我扔”。

0

方法m2可能会抛出一个IOException
由于m1调用m2m1也可能会抛出此异常。
IOException不是从RuntimeException派生的,所以它可能被抛出的事实应该被明确地声明。
换句话说,将throws IOException添加到m1的声明中。

0

任何调用引发任何Checked异常的方法的方法都必须处理它们或抛出它们。如果不是通过捕获来处理,那么在该方法的签名中必须声明异常,以使得这种方法的调用者知道要处理的异常。检查异常是针对某些特殊情况的故意,必须予以处理或抛出。在你的情况下,因为m2()抛出一个checkedException和m1()调用m2()因此它是m1()的方法的签名的责任,让任何呼叫者m1()知道有必要处理的例外情况的可能性。请注意,在你的情况下,你只是从主要方法调用它,但不会阻止你或任何其他开发人员在将来中使用任何其他方法调用它。引发检查异常的方法的责任是声明存在异常情况并需要处理,调用者只是处理它们。

希望您现在明白您需要修改m1()的签名并为IOException添加缺少的声明。

0

让我们看看JLS: 11.3. Run-Time Handling of an Exception说什么。

当一个异常被抛出(§14.18),控制从导致该异常到最近的代码传送动态包围catch子句,如果有的话,在try语句(§14.20),其能够处理该异常的。

...

如果无法找到能够处理异常的catch子句,那么当前线程(即遇到异常的线程)终止。结束之前,所有的最终条款是根据以下规则执行,未捕获异常的处理:

和之后的例子:

方法运动员的声明必须有一个throws子句,因为它可以抛出TestException异常,这是一个检查的异常类(§11.1.1)。如果throws子句被省略,则会发生编译时错误。

这最后一条语句恰好就是您的情况,m1省略了throws子句,因此会发生编译时错误。添加throws IOException或此异常的任何超类/接口来纠正此错误。

注: 有趣的是,要注意的是,如果你试图抓住从main一个IOException与你实际的代码,你会得到一个其他的编译时错误追赶一辆unthrowned例外。但Exception不是这种情况,因为这只发生在检查异常,因为Exception可以但未经检查的异常RuntimeException,情况并非如此。

更多信息JLS : 11.2. Compile-Time Checking of Exceptions

相关问题