尝试/捕获与抛出exception

这些代码语句是否相同? 他们之间有什么区别?

private void calculateArea() throws Exception { ....do something } 

 private void calculateArea() { try { ....do something } catch (Exception e) { showException(e); } } 

是的,有一个巨大的差异 – 后者会吞噬exception(无可否认),而第一个则会让它传播。 (我假设showException不会重新抛出它。)

所以,如果你调用第一个方法,“做某事”失败,那么调用者将不得不处理这个exception。 如果你调用第二个方法,并且“做某事”失败,那么调用者将不会看到任何exception…这通常是一件坏事,除非showException 真的处理了exception,修正了错误,肯定calculateArea已经达到了目的。

你可以告诉这一点,因为你不能自己调用​​第一个方法, 或者声明你的方法可能抛出Exception

是。 声明throws Exception的版本将需要调用代码来处理exception,而明确处理它的版本则不会。

即简单地说:

 performCalculation(); 

将处理exception的负担转移给主叫方:

 try { performCalculation(); catch (Exception e) { // handle exception } 

第一个throws Exception ,所以调用者需要处理Exception 。 第二个在内部捕获和处理Exception ,所以调用者不必做任何exception处理。

是的,他们之间有很大的区别。 在第一个代码块中,您将exception传递给调用代码。 在第二个代码块中,你自己处理它。 哪种方法是正确的,完全取决于你在做什么。 在某些情况下,您希望代码处理exception(例如,如果没有find文件并且想要创build该文件),但是在其他情况下,您希望调用代码处理exception(找不到文件他们需要指定一个新的或创build它)。

一般来说,你也不想捕捉一个通用的exception。 相反,您只需要捕获特定的文件,如FileNotFoundExceptionIOException因为它们可能意味着不同的事情。

有一种情况我们不能使用抛出,我们必须使用try-catch。 有一个规则:“重写的方法不能抛出任何额外的exception,而不是其父类抛出”。 如果有任何额外的exception应该使用try-catch来处理。 考虑这个代码片段。 有一个简单的基类

 package trycatchvsthrows; public class Base { public void show() { System.out.println("hello from base"); } } 

它的派生类:

 package trycatchvsthrows; public class Derived extends Base { @Override public void show() { // TODO Auto-generated method stub super.show(); Thread thread= new Thread(); thread.start(); try { thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // thread.sleep(10); // here we can not use public void show() throws InterruptedException // not allowed } } 

当我们不得不调用thread.sleep()时,我们不得不使用try-catch,在这里我们不能使用:

  public void show() throws InterruptedException 

因为重写的方法不能抛出额外的exception。

我认为,“相同”是指行为。

函数的行为可以通过以下方式确定:

1)退货价值

2)抛出exception

3)副作用(即在堆,文件系统等的变化)

在这种情况下,第一个方法传播任何exception,而第二个方法不抛出检查exception,并吞下大部分未经检查的exception,所以行为是不同的。

然而,如果你保证“做某事”从不抛出exception,那么行为将是相同的(尽pipe编译器将要求调用者在第一个版本中处理exception)

– 编辑 –

从APIdevise的angular度来看,这些方法在合同上是完全不同的。 此外,不build议抛出类Exception。 尝试抛出更具体的东西,让调用者更好地处理exception。

如果你抛出一个exception,子方法(覆盖这个)应该处理exception

例:

 class A{ public void myMethod() throws Exception{ //do something } } A a=new A(); try{ a.myMethod(); }catch Exception(e){ //handle the exception } 

这个方法的调用者将需要捕获这个exception,或者声明它在方法签名中被重新抛出。

 private void calculateArea() throws Exception { // Do something } 

在下面的try-catch块示例中。 这个方法的调用者不必担心处理exception,因为它已经被处理了。

 private void calculateArea() { try { // Do something } catch (Exception e) { showException(e); } } 

很多时候你希望调用者处理这个exception。 假设调用者调用另一个调用另一个方法的方法,而不是让每个方法处理这个exception,你可以在调用者处理它。 除非你想在这个方法失败时在其中的一个方法中做某件事。