【问题标题】:Java Asynchronous Exceptions: Can I catch them?Java 异步异常:我能捕捉到它们吗?
【发布时间】:2012-11-10 12:13:18
【问题描述】:

我一直在阅读 JLS,遇到了我引用的 11.1.3. Asynchronous Exceptions 部分:

大多数异常是同步发生的,因为 它们发生的线程,以及程序中的某个点 指定可能导致此类异常。一个异步 相比之下,异常是可能发生在 程序执行中的任何一点。

异步异常仅由于以下原因而发生:

[...]

  • Java 虚拟机中的内部错误或资源限制阻止它实现 Java 编程语言。在这种情况下,异步异常 抛出的是 VirtualMachineError 子类的一个实例。

是否有可能捕获此类异常以用于日志记录或通知(因为我相信这样的事情是不可恢复的)?我怎样才能做到这一点?

【问题讨论】:

    标签: java exception virtual-machine


    【解决方案1】:

    您可以像捕获任何其他异常一样捕获此类异常。唯一的问题是它们可能出现在程序中的任何位置,因此很难可靠地捕获它们。您基本上必须将所有线程的 run 方法和 main 方法包装在 try..catch 块中,但是对于您无法控制的线程(例如 Swing EDT 或计时器等)。

    通常也不建议捕获Error 的任何子类,因为JVM 可能处于不稳定状态,这可能会导致进一步的故障(例如OutOfMemoryError 的情况下,您甚至可能没有足够的内存到异常处理)。但是,日志记录将是在我眼中捕捉Errors 的正当理由。

    我建议的解决方案是通过setting it as the default exception handler 使用uncaught exception handler。在此处理程序中,您将获得所有异常和错误,如果它们没有在代码中的任何地方捕获,您可以尝试记录它们。

    【讨论】:

    • 如果想知道try-catch 块是否可以在try 块内,是的,你可以拥有它。 Relevant code.
    • @Prasanth 当然,try..catch 可以出现在正常语句可能出现的任何地方,这包括嵌套的try。当然,您也可以在另一个 catch 中添加一个 try..catch
    • 我不明白添加try..catch 块如何帮助捕获此类异常。我有这样的情况,添加一个“内部”try--catch 对我的情况没有帮助。你能详细说明一下吗? @Prasanth @Philipp Wendler?
    • @MichaelTrouw 在这种情况下,异常可能是在您的线程不在 try 块内时引发的。
    • @PhilippWendler 我刚刚发现调试时发生了什么。捕获从未执行,因为异常是在较低(库)级别处理的。我把它们扔掉了,所以它们按预期冒泡了,而且似乎这不是一个异步任务。给 Java 初学者的好提示,异常 102:检查你期望的异常是否真的被抛出了!
    【解决方案2】:

    没有必要捕捉这些异常(VirtualMachineError 的子类),因为您不知道 pogram 处于何种状态,文档说虚拟机错误:

    Java 虚拟机实现抛出一个对象,该对象是 VirtualMethodError 类的子类的实例,当 内部错误或资源限制阻止它实施 本章描述的语义。 本规范不能 预测内部错误或资源限制可能在哪里 遇到并且没有明确规定何时可以报告

    因此,假设您遇到 OutOfMemoryError 或 UnknownError ,您无能为力,并且一旦您的 vritualmashine 无法正常工作,您将无法为用户提供任何帮助,因为您的程序也无法正常工作,此外您不知道它发生的时间、地点和原因,因为它不是由您的程序引起的代码错误。

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      • 2012-01-10
      • 1970-01-01
      • 2015-11-21
      • 2020-04-20
      相关资源
      最近更新 更多