catch块是否能够捕获Throwable(错误和异常)

时间:2011-07-21 06:41:50

标签: java exception

在我的一次采访中,他们问我,是否有可能在catch()中写出Throwable

try{
some code
}
catch(Throwable t)
{
}

我说是的。它不会给出编译时错误,但是如果出现Error(Throwable的子类),jvm将无法处理它,因为错误是jvm无法处理的不可逆条件。比他们进一步询问的还有什么是写作Throwable的用法。

请给我正确的回复我们可以使用Throwable in catch。如果是的话。

5 个答案:

答案 0 :(得分:11)

可以捕获Throwable。是的,您还将捕获java.lang.Error的实例,这对于例如OutOfMemoryError来说是一个问题。 Throwable的。一般来说,我不会抓住main的。如果必须,您应该在调用堆栈的最高位置执行此操作,例如{{1}}方法(您可能希望捕获它,记录它并重新抛出它)。

我同意你的论证,捕捉你无法处理的事件是没有意义的(例如OutOfMemoryError)。一篇不错的帖子是here

答案 1 :(得分:2)

是的,可以抓住Throwable

如果发现错误,JVM /应用程序是否能够继续运行取决于发生的实际错误,导致错误的原因以及您的应用程序接下来会做什么(如果有的话)。

  • 在某些情况下,JVM可能处于如此糟糕的状态,无法恢复。

  • 在某些情况下,JVM很好......只要你不做某些事情。类加载错误就是一个很好的例子。如果您的应用程序不尝试使用您无法加载的类或依赖类,则可以继续。 (实际上,如果没有无法加载的类,应用程序就不会继续运行......但如果是,则可以。)

  • 在某些情况下,核心JVM会很好,但是可能已经对应用程序的数据结构和/或其线程和计算状态进行了未指定的损坏。 OOME可能会对您这样做,特别是如果您的应用程序不是为处理意外死亡的线程而设计的。

  • 另一个原因是从OOME捕获和恢复是有问题的。虽然当前计算的终止将释放一些堆空间,但很有可能它不会释放足够的空间。因此,您可以轻松地进入您的应用程序反复抛出和捕获大量OOME并且没有取得实际进展的情况。

所有这些意味着尝试从错误中恢复通常是一个坏主意。这与错误的javadoc所说的一致:

  

“错误是Throwable的子类,表示合理的应用程序不应该试图捕获的严重问题。”

答案 2 :(得分:1)

  • 是的,我们可以抓住Throwable但是作为最佳做法,建议不要抓住Throwable
  • 捕获Throwable也包括Errors,我们不应该发现错误,这有助于识别JVM问题。

答案 3 :(得分:0)

可以使用Throwable代替任何单个异常/错误。但是建议通过ThreadDeadException。所以你可以为它添加额外的catch子句,或者按类型过滤。

答案 4 :(得分:0)

捕获Throwable将捕获所有异常(包括RuntimeExceptions)和所有错误。建议不要捕获任何父Throwables(Throwable,Error,Exception或RuntimeException),但如果方法抛出过多的已检查异常或抛出异常,则发现这种情况并不罕见。

在某些API中将方法记录为抛出异常并不罕见。这以牺牲控制为代价提供了一些灵活性。我喜欢定义一个新的Exception类来处理这种情况,但这是个人偏好。

以下简单类显示了throwable类型和相应catch块的样本。

public class ThrowableExamples {

    public static void main(String[] args) {
        try {
//          throw new NoSuchMethodException("Exception");
//          throw new Exception("Exception");
//          throw new IllegalStateException("RuntimeException");
//          throw new RuntimeException("RuntimeException");
            throw new NoSuchMethodError("Error");
//          throw new Error("Error");
//          throw new Throwable("Throwable");

        } catch (RuntimeException e) {
            System.out.println("Caught RuntimeException: " +  (e.getMessage().equals("RuntimeException") ? "Expected" : "Unexpected"));

        } catch (Exception e) {
            System.out.println("Caught Exception: " +  (e.getMessage().equals("Exception") ? "Expected" : "Unexpected"));

        } catch (Error e) {
            System.out.println("Caught Error: " +  (e.getMessage().equals("Error") ? "Expected" : "Unexpected"));

        } catch (Throwable e) {
            System.out.println("Caught Throwable: " +  (e.getMessage().equals("Throwable") ? "Expected" : "Unexpected"));
        }
    }
}