Java 为什么要费心设置;sun.awt.exception.handler“;财产?
下面是一些捕获在事件分派线程上引发的异常的代码:Java 为什么要费心设置;sun.awt.exception.handler“;财产?,java,swing,awt,uncaught-exception,Java,Swing,Awt,Uncaught Exception,下面是一些捕获在事件分派线程上引发的异常的代码: package com.ndh.swingjunk; import java.awt.EventQueue; import javax.swing.JFrame; public class EntryPoint { public static void main(String[] args) { Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHan
package com.ndh.swingjunk;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class EntryPoint {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
// System.setProperty("sun.awt.exception.handler", MyExceptionHandler.class.getName());
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new SomeWindow("foo").setVisible(true);
}
});
}
}
class SomeWindow extends JFrame {
public SomeWindow(String title) {
this.setTitle(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
throw new RuntimeException("hello");
}
}
我已经看到警告,事件分派线程上抛出的异常不会由UncaughtExceptionHandler处理,但我的示例中似乎不是这样;无论注册行是被注释掉还是保留在中,其工作原理都是相同的。我的示例不知怎么搞砸了,还是不再需要向
sun.awt.exception.handler
注册异常处理程序了?您调用了setDefaultUncaughtExceptionHandler
,而不是setUncaughtExceptionHandler
。(如果存在SecurityManager
:前者需要RuntimePermission setDefaultUncaughtExceptionHandler
;后者为SecurityManager.checkAccess(Thread)
)EDT类(java.awt.EventDispatchThread
,不要在javadoc中查找,该类是包私有的)自从AWT的起源以来已经发生了很大的变化
在JDK6中,您可以看到该类现在可以正确处理EDT内部发生的异常。在当前版本中,异常处理有点复杂:
- 如果你已经设置了
property, 然后将调用您的处理程序 开发人员的 在EDT内调用的代码 (与以前的JDK兼容) 版本(已确保)sun.awt.exception.handler
- 否则,任何例外都将被删除
重新下载,因此将停止当前EDT和任何默认设置
将被删除 能够捕捉到它,就像你的代码片段一样 证明UncaughtExceptionHandler
EventQueue
管理相当复杂,我甚至敢说“凌乱”:很多代码看起来像黑客)
在这种情况下,异常将被记录到System.err
,除非您设置了sun.awt.exception.handler
属性。使用默认的UncaughtExceptionHandler
不会有帮助
因此,我的看法是,是的,您仍然需要处理
sun.awt.exception.handler
属性,除非您可以确定您的应用程序不使用模态对话框(不要忘记JOptionPane
对话框也是模态的).FYI,此属性已在Java7中删除。模态对话框现在正确使用Thread.UncaughtExceptionHandler:Hawtin我希望我的JavaFX UI在出现未捕获错误时弹出一个消息框。您能澄清我应该使用哪个调用吗?@Anil如果它是不受信任的插件/WebStart应用程序,则必须是setUncaughtExceptionHandler
。理论上,我认为您应该只在事件线程上使用JavaFX,因此您只需要设置一次(但请确保在正确的线程上)。如果没有实现的组件,AWT EDT可以退出并由另一个线程替换,因此存在一个潜在的风险,这是不够的,如果这很重要的话。Hawtin JavaFX也使用任务和工作线程作为后台线程,我正在使用它们。我不知道这是否“正确”,但我做的是:在控制器-UI线程中,我调用ed`Thread.currentThread().setUncaughtExceptionHandler(新的Thread.UncaughtExceptionHandler(){@Override public void uncaughtException(线程t,Throwable e){OKCanceController okc=null;okc=replaceScenceContent(okc,“ok_cancel.fxml”,“应用程序有错误:”+e.getMessage();}})`