2012-11-22 42 views
13

我一直在读JLS,我遇到了我从中引用部分11.1.3. Asynchronous Exceptions:同步发生Java异步异常:我可以捕获它们吗?

大多数例外,通过在它们发生的 线程的行为的结果,并在一个点指定的 程序可能导致此类异常。相反,一个异步 异常可能会发生在程序执行的任何一点的 处的异常。

而且

异步例外只发生作为结果:

[...]

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

是否有可能赶上用于日志记录或通知这样的例外(因为我相信这样的事情是不可恢复的)?我怎么能做到这样的事情?

回答

10

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

通常不推荐使用Error的任何子类,因为JVM可能处于不稳定状态,这可能会导致进一步的故障(例如在OutOfMemoryError的情况下,您甚至可能没有足够的内存异常处理)。但是,记录会成为我眼​​中捕获Error的有效理由。

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

+0

对于任何想知道'try-catch'块是否可以在'try'块中,是的,你可以拥有它。 [相关代码](http://ideone.com/stN75L)。 – Prasanth

+1

@Prasanth当然,'try..catch'可以在任何地方都可以正常使用,这包括嵌套'try'。例如,当然你也可以在另一个“catch”中有一个'try..catch'。 –

+0

我不明白添加'''try..catch''块如何帮助捕获这样的异常。我有这种情况,并增加一个'内部'''try - catch'''没有帮助我的情况。你能详细说明一下吗? @Prasanth @Philipp Wendler? –

3

有没有因为你没有indecattion在该状态下pogram是在点捕获这些异常(的VirtualMachineError的子类)的点,关于虚拟机错误的文件saies:

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

所以假设你在一个OutOfMemoryError或不明错误没有太多可以做它得到的,而一旦你vritualmashine does not工作正常,你不能向用户提供anyhelp为你的程序的心不是正常的工作,以及,除了你有不知道它发生在什么时间,地点和原因,因为它不是由程序引起的代码错误。