2011-04-14 48 views
2

我是Java新手,并试图理解Java中的异常。Java中的例外

class MyException extends Exception { 

     void someMethod() { 
      doStuff(); 
     } 

     void doStuff() throws MyException { 

     try { 
      throw new MyException(); 
      } 

      catch(MyException me) { 
      throw me; 
      } 
     } 
} 

此程序会产生错误:

java:3: unreported exception MyException; must be caught or declared to be thrown

doStuff(); 
     ^

try和catch块的doStuff()方法中写入。另外doStuff()方法“抛出”MyException,那么为什么还需要在someMethod()中丢掉MyException呢?

+0

多数民众赞成在这种情况下,你抛出异常 – 2011-04-14 01:24:01

+0

只是一个说明...检查异常几乎是一个Java idiosynchrasy:他们不*在OOA/OOD水平存在,并有很多语言完成很好**那个“概念”。有些人甚至认为检查异常是:* a)*荣耀的GOTO语句,* b)*应该被排除在语言之外的Java错误,* c)*不惜一切代价避免(* Spring *框架浮现在脑海中,但它远非唯一)。你还有一大堆在JVM之上运行的语言,它决定让这个“特性*出语言......例如 – SyntaxT3rr0r 2011-04-14 08:46:42

+0

...... 250 000中等代码库,在这里我们没有定义一个单一的checked异常和我们没有抛出单个检查异常的地方。所以,你需要阅读关于检查异常的内容。 :) – SyntaxT3rr0r 2011-04-14 08:48:14

回答

7

确实发现了MyException,但是您重新抛出它,因此需要捕获一个新的活动异常。

这被称为检查异常。每次调用doStuff()方法时,都需要将其封装在MyException的try/catch中,或者可以声明您的方法也会抛出MyException。

这保证了在编码过程中至少会考虑已知的异常。

+0

重新抛出异常并不是真正的主要问题。关键是doStuff()被声明为能够抛出异常,并且检查异常,因此您必须在someMethod()中处理它(或允许它传播)。 – davmac 2011-04-14 02:47:54

+0

@davmac - 你是对的,但是如果它被声明了,但是从来没有被抛出,它就像移除throws子句一样是一个有效的修复... – 2011-04-17 01:42:58

+0

@Joe Zitzelberger - 不一定,异常规范是方法接口。您可能希望子类可以重写方法定义的方式导致异常被抛出。无论如何,我的观点是提问者得到一个错误,并且错误是由于声明该方法抛出一个异常,而不是由于它实际抛出异常。 – davmac 2011-04-18 01:26:02

2

doStuff()方法的主体中有什么并不重要 - 因为您已声明它“抛出MyException”,那么调用方法(在此例中为someMethod())必须要么处理异常(通过try/catch块),要么声明自己抛出相同的异常。在后一种情况下,doStuff()抛出的异常会自动传播给someMethod()的调用者。

换句话说:您在doStuff()中捕获异常并不重要,因为doStuff()被声明为抛出异常。你甚至可以删除doStuff()的方法主体(使其不做任何事情),你仍然必须在someMethod()中处理异常。

2

由于doStuff()再次抛出异常。你将不得不再次围绕尝试抓住它。

void someMethod() { 

     try 
     { 
     doStuff(); 
     } 
     catch (MyException e) 
     { 
     e.printStackTrace(); 
     } 

    } 

或者另一种选择是不要再抛出异常。每次你抛出一个异常,它都必须被捕获。

3

你需要“重投”从的someMethod的异常,因为MyException是“的Checked Exception”(不继承RuntimeException - 这是一个“未经检查的异常”)和编译器会强迫你处理检查异常,就像这样:

class MyException extends Exception { 

    /** 
    * @throws MyException because it is a checked Exception (doesn't extend RuntimeException) and the compiler 
    * forces you to handle Checked Exceptions. 
    */ 
    void someMethod() throws MyException { 
     doStuff(); 

    } 

    void doStuff() throws MyException { 
     try { 
      throw new MyException(); 
     } catch (MyException me) { 
      throw me; 
     } 
    } 
} 

或者你需要处理MyException一些方法,以便编译器是幸福的,就像这样:

class MyException extends Exception { 


    void someMethod() { 
     try { 
      doStuff(); 
     } catch (MyException ex) { 
      //Do Something useful with the Exception... 
      Logger.getLogger(MyException.class.getName()).severe("A Severe Exception Message"); 
     } 

    } 

    void doStuff() throws MyException { 
     try { 
      throw new MyException(); 
     } catch (MyException me) { 
      throw me; 
     } 
    } 
}