【问题标题】:How does throw new exception inside a catch work?在 catch 中抛出新异常如何工作?
【发布时间】:2012-08-02 19:18:40
【问题描述】:

我有一个sn-p如下:

try
{
   //blah!!
} 
catch(IOException e)
{
   throw new RuntimeException(e);
}

我不明白上面的工作原理是什么?它会catchIOException 吗?当它这样做时,它会throwRuntimeException 吗?在那种情况下,IOException 将没有任何意义,对吧?举个例子会有所帮助。

【问题讨论】:

  • 你是对的。当您想抛出自己的异常而不是系统默认值时,它非常有用(例如,更改异常消息或添加一些提示出了什么问题以及如何修复它)
  • 是的,上面的代码会捕获(并丢弃)IOException,然后抛出一个RuntimeException。不一定是好的编码实践,但完全合法的 Java。异常是一个对象,一旦被捕获,与任何其他对象相比就没有特殊状态——它可以被忽略(并被 GC 清理)、作为参数传递、重新抛出等等。
  • @Hot Licks IOException 被包裹在 RuntimeException 中,如果你不喜欢检查的异常,这不一定是坏事。

标签: java exception-handling try-catch


【解决方案1】:

您对某些假设是正确的,但您应该更深入一点。 在您的try 块内,假设您的类的一个方法抛出了这种异常IOException。因此,catch 将作为您处理这种特殊情况的方式。基本上就是这样。如果您只是使用 RuntimeException 丢弃异常,但正如您所做的那样,将您的 IOException 包装在 RuntimeException 中,您根本不会丢失它。

正常使用是在更高级别对待您的异常。这里有一个很好的异常处理教程,请查看:Best Practices for Exception Handling

【讨论】:

    【解决方案2】:

    在此代码中,已检查的 IOException 变为有效地未检查。通过将 IOException 传递给 RuntimeException,您将 2 链接在一起。

    【讨论】:

      【解决方案3】:

      是的,您的理解是正确的。这在您想要显示应用程序特定异常而不是 java 提供的异常的情况下可能很有用(IOException 可能不是理解这一点的完美案例)。

      【讨论】:

        【解决方案4】:

        你的理解是正确的。如果IOException 被抛出,catch 处理程序将捕获它,然后立即抛出它自己的RuntimeException。这个异常可能在程序的其他地方被捕获,在这种情况下,控制将在处理程序处获得,或者它不会被捕获并终止当前线程。

        考虑这里发生的事情的一种方法如下 - IOException 是已检查异常,这意味着它必须被捕获。如果它没有被捕获,那么程序将无法编译。上面的代码说,每当它捕获到一个IOException,它就会抛出一个RuntimeException,这是一个未经检查的异常。如果程序员不想捕获此异常,则不必捕获它。请注意,这个RuntimeException 是使用捕获的IOException 作为参数构造的。这意味着如果 RuntimeException 稍后被捕获,任何捕获它的人都可以注意到根本原因是 IOException 并可以相应地处理它。

        希望这会有所帮助!

        【讨论】:

          【解决方案5】:

          检查过的Exceptions 必须被捕获或声明为抛出。 RuntimeExceptions 不这样做,因此作为RuntimeException 捕获和重新抛出是避免必须声明的方法:

          public void myMethod() throws IOException
          

          throw new RuntimeException(e); 被调用时,会创建一个新的异常并抛出一个异常,但原始异常会被包裹在其中。所以堆栈跟踪将如下所示:

          Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Some error.
              at com...main(SomeClass.java:36)
          Caused by: java.io.IOException: Some error.
          

          所以调用堆栈上的实际异常是RuntimeException,但原始IOException 保留在消息中作为根本原因。

          【讨论】:

            【解决方案6】:

            没有。 RuntimeException 有一些特别之处。当您想抛出 RuntimeException 时,方法签名中不需要 throws RuntimeException。这称为未经检查的异常。此代码将 IOException 包装到 RuntimeException 中并将其重新抛出给调用者,恕我直言,在大多数情况下,这是一种不好的方法。

            RuntimeException 的所有子类都未选中,如 IllegalArgumentException、NullPointerException 等...

            【讨论】:

            • RuntimeException 与许多其他异常相比并没有什么特别之处。它是“未经检查的”,但这纯粹是一个编译器约定(JVM 对这个概念一无所知),还有许多其他“未经检查”的异常。
            • 这通常是 Java 中最不坏的选择,例如在实现您无法控制的接口(API 的一部分)时。您不想丢弃异常,但不允许让它转义接口方法。简单示例:Runnable.run - 所以你抛出 RuntimeException 代替。
            • @DanielEarwicker:是的,我也在考虑这个问题,公平点。但我认为 Runnable.run 是一个不好的例子。因为你不自己调用 run 方法。它被另一个线程调用。当抛出异常时,线程将死亡,应用程序的其他部分将不知道。
            猜你喜欢
            • 2014-06-19
            • 2020-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-18
            • 1970-01-01
            • 2012-09-21
            相关资源
            最近更新 更多