为什么要设置"sun.awt.exception.handler"属性呢?

Nat*_*hes 8 java swing awt uncaught-exception

这里有一些代码可以捕获Event Dispatch Thread上抛出的异常:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经看到警告,事件调度线程抛出的异常不会被UncaughtExceptionHandler处理,但对我的例子来说似乎并非如此; 无论注册行是注释掉还是遗留下来,它的工作方式都是一样的.我的示例是以某种方式搞砸了,还是注册了sun.awt.exception.handler不再需要的异常处理程序?

jfp*_*ret 15

EDT类(java.awt.EventDispatchThread,别看它在javadoc中,这个类是包私有),因为AWT的起源有了很大的变化.

JDK6中,您可以看到此类现在可以正确处理EDT内发生的异常.当前版本中的异常处理有点复杂:

  • 如果你已经设置了 sun.awt.exception.handler属性,那么将为在EDT内部调用的开发人员代码抛出的每个异常调用你的处理程序(确保与以前的JDK版本的兼容性).
  • 否则,任何异常将被 再次抛出,因此将停止当前EDT,任何默认 UncaughtExceptionHandler就能抓住它,因为你的片段演示.

但是(这非常重要),如果你仔细查看EDT的代码,你会发现如果在显示模态对话框时EDT中发生异常,这种机制将不起作用(我猜这是因为EDT而EventQueue管理是相当复杂的,我甚至敢说" ":大量的代码看起来像黑客在那里).

在这种情况下,System.err除非您已设置sun.awt.exception.handler属性,否则将记录异常.有默认值UncaughtExceptionHandler无济于事.

所以我对此的看法是,是的,你仍然应该打扰sun.awt.exception.handler属性,除非你可以确定你的应用程序不使用模态对话框(不要忘记JOptionPane对话框也是模态的).

  • 仅供参考,此属性已在Java7中删除.模态对话框现在正确使用Thread.UncaughtExceptionHandler:http://bugs.sun.com/view_bug.do?video_id = 6727884 (11认同)