Java 异步异常:我可以捕获它们吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13506900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:01:20  来源:igfitidea点击:

Java Asynchronous Exceptions: Can I catch them?

javaexceptionvirtual-machine

提问by ElderMael

I have been reading the JLS and I encountered the section 11.1.3. Asynchronous Exceptionsfrom which I quote:

我一直在阅读JLS,遇到了11.1.3我引用的异步异常

Most exceptions occur synchronously as a result of an action by the thread in which they occur, and at a point in the program that is specified to possibly result in such an exception. An asynchronous exception is, by contrast, an exception that can potentially occur at any point in the execution of a program.

大多数异常作为发生它们的线程的操作的结果而同步发生,并且在程序中指定可能导致此类异常的点处发生。相比之下,异步异常是一种可能在程序执行过程中的任何一点发生的异常。

And

Asynchronous exceptions occur only as a result of:

[...]

  • An internal error or resource limitation in the Java virtual machine that prevents it from implementing the semantics of the Java programming language. In this case, the asynchronous exception that is thrown is an instance of a subclass of VirtualMachineError.

异步异常仅在以下情况下发生:

[...]

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

Is it possible to catch such exceptions for logging purposes or notification (because I believe such thing is unrecoverable)? How can I achieve such thing?

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

采纳答案by Philipp Wendler

You can catch such exceptions just like any other exception. The only problem is that they may occur at anyplace in your program, so catching them reliably is hard. You would basically have to wrap the runmethod of all threads and the mainmethod in a try..catchblock, but you can't do that for threads you don't control (like the Swing EDT, or threads for timers etc.).

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

Also catching any subclass of Erroris usually not recommended, because the JVM may be in an unstable state, which might lead to a further failure (for example in the case of OutOfMemoryError, you might not even have enough memory to to the exception handling). However, logging would be a valid reason for catching Errors in my eyes.

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

My suggested solution would be to use an uncaught exception handlerfor this by setting it as the default exception handler. In this handler you will get all exceptions and errors, if they are not caught anywhere in the code, and you can try to log them.

我建议的解决方案是为此使用未捕获的异常处理程序,方法是将其设置为默认异常处理程序。在这个处理程序中,您将获得所有异常和错误,如果它们没有在代码中的任何地方被捕获,您可以尝试记录它们。

回答by CloudyMarble

There is no point of catching these exceptions (Subclasses of VirtualMachineError) as you have no indecattion in which state the pogram is at the point, the Doc saies about Virtual Machine Errors:

没有必要捕获这些异常(VirtualMachineError 的子类),因为您没有说明 pogram 处于哪个状态,文档说虚拟机错误:

A Java virtual machine implementation throws an object that is an instance of a subclass of the class VirtualMethodError when an internal error or resource limitation prevents it from implementing the semantics described in this chapter. This specification cannot predict where internal errors or resource limitations may be encountered and does not mandate precisely when they can be reported.

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

so assuming you get in an OutOfMemoryError or an UnknownError there isnt much you can do about it, and once your vritualmashine doesnt work properly you cant provide the user anyhelp as your program isnt working properly as well, besides you have no idea at what time, point, and reason it happends since its not a code error that was caused from your program.

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