捕捉和抛出异常:发生了什么"引擎盖下#34;?

时间:2015-10-26 15:13:51

标签: java exception try-catch

我不熟悉错误/异常处理。 发生了什么"引擎盖下#34;当例外是caughtthrown时?

即。在try-catch块中捕获异常然后抛出它有什么意义呢?

E.g:

  try {
        //Stuff
    } catch(StuffException e) {
        throw new MyException();
    }
}

4 个答案:

答案 0 :(得分:5)

关于异常机制的内部工作原理:有很多关于此的文档。 我特别喜欢这篇文章: http://www.javaworld.com/article/2076868/learn-java/how-the-java-virtual-machine-handles-exceptions.html

超短摘要:当抛出异常时,jvm在一个表中查找,其中继续执行(异常的init()方法)。

对于问题的第二部分:

  

在try-catch块中捕获异常然后抛出它有什么意义?

我看到了抓住另一个例外的一些原因:

  • 您可能想要捕获未经检查的异常(因为您知道, “可能会发生一些不好的事情”)并抛出一个检查过的 - 所以调用者必须处理它。

  • 您想要使用自定义异常,可能需要额外的 信息/逻辑

  • 您正在实施错误外观,例如抛出异常和 在门面的最后抓住它们。

答案 1 :(得分:2)

您的示例捕获具有StuffException类型的内容,然后抛出MyException。这样做是为了抽象出原始的异常;可能是原始异常是一个实现细节,调用它的东西不需要知道(以及哪些需要能够改变,以便调用者不应该依赖它),并抛出异常替换它是已发布的API的一部分,调用者可以依赖它。这是Hibernate的情况,它捕获在调用JDBC函数过程中生成的SQLExceptions,并将它们包装在Hibernate异常中,因此调用代码将它们识别为从Hibernate抛出,并且调用代码不直接依赖于JDBC异常,但是在Hibernate上。如果JDBC改变了它抛出的异常,那么一旦Hibernate适应它,Hibernate的用户就不必改变了。

这个例子的坏处是当e超出范围时,原始StuffException的stacktrace信息被丢弃,而MyException的stacktrace以抛出MyException的位置开始,这使得很难找到实际问题的根源。将旧异常分配给新异常作为其原因将保留原始堆栈跟踪信息:

try {
        //Stuff
    } catch(StuffException e) {
        MyException myException = new MyException();
        myException.initCause(e);
        throw myException;
    }
}

答案 2 :(得分:0)

异常用于处理程序流中通常不会发生的事情。再次抛出异常的重点是更改异常类型,如示例所示。这样做,您可以创建一个自定义异常并将其抛入另一个异常catch块。

修改

以下是一个例子:

假设您有一个适用于Thread的方法。你的方法内部有延迟:

Thread.sleep(3000);

但如果你这样写,你会得到一个错误,因为sleep方法声明如下:

void java.lang.Thread.sleep(long millis) throws InterruptedException

所以你必须抓住异常:

try{
Thread.sleep(3000);
}catch(InterruptedException e){
//do stuff
}

现在,您不喜欢InterruptedException,并且希望使用自己的自定义异常来处理它。但是你怎么做,因为睡眠方法只抛出那个特定的异常?答案是:

try{
Thread.sleep(3000);
}catch(InterruptedException e){
throw new CustomException();
}

此时,如果引发了InterruptedException,它将被捕获并且将引发一个CustomException。

答案 3 :(得分:0)

捕获然后抛出异常的一些可能用法:

  • 异常翻译
    • 用未经检查的例子替换已检查的例外
    • 使用调用者可以更好地处理的一些常规异常来翻译特定于实现的异常
  • 向异常添加更多上下文/附加信息(例如,某些低级方法失败,您希望识别失败的输入)
  • 执行其他操作(例如,在将错误发送给调用者之前记录错误)
  • 处理更复杂的异常层次结构

    • e.g。如果您想要捕获除IOExceptionFileNotFoundException的子类型)之外的所有IOException,您可以这样做:

      try {
          ...
      }
      catch (FileNotFoundException e) {
          throw e;
      }
      catch (IOException e) {
          // handle exception
      }