我正在使用一个名为 MyExceptionHandler
的类,它实现了 Thread.UncaughtExceptionHandler
来处理我项目中的正常异常。
据我了解,此类无法捕获 EDT 异常,因此我尝试在 main()
方法中使用它来处理 EDT 异常:
public static void main( final String[] args ) {
Thread.setDefaultUncaughtExceptionHandler( new MyExceptionHandler() ); // Handle normal exceptions
System.setProperty( "sun.awt.exception.handler",MyExceptionHandler.class.getName()); // Handle EDT exceptions
SwingUtilities.invokeLater(new Runnable() { // Execute some code in the EDT.
public void run() {
JFrame myFrame = new JFrame();
myFrame.setVisible( true );
}
});
}
但直到现在它还没有工作。例如,在初始化 JFrame 时,我从构造函数中的捆绑文件加载其标签,如下所示:
setTitle( bundle.getString( "MyJFrame.title" ) );
我从捆绑文件中删除了 key MyJFrame.title
以测试异常处理程序,但它不起作用!异常通常打印在日志中。
我在这里做错了吗?
最佳答案
EDT 异常处理程序不使用 Thread.UncaughtExceptionHandler
。相反,它调用具有以下签名的方法:
public void handle(Throwable thrown);
将它添加到 MyExceptionHandler
,它应该可以工作。
这方面的“文档”可以在 EventDispatchThread
中找到,它是 java.awt
中的一个包私有(private)类。从 handleException()
那里引用 javadoc:
/**
* Handles an exception thrown in the event-dispatch thread.
*
* <p> If the system property "sun.awt.exception.handler" is defined, then
* when this method is invoked it will attempt to do the following:
*
* <ol>
* <li> Load the class named by the value of that property, using the
* current thread's context class loader,
* <li> Instantiate that class using its zero-argument constructor,
* <li> Find the resulting handler object's <tt>public void handle</tt>
* method, which should take a single argument of type
* <tt>Throwable</tt>, and
* <li> Invoke the handler's <tt>handle</tt> method, passing it the
* <tt>thrown</tt> argument that was passed to this method.
* </ol>
*
* If any of the first three steps fail then this method will return
* <tt>false</tt> and all following invocations of this method will return
* <tt>false</tt> immediately. An exception thrown by the handler object's
* <tt>handle</tt> will be caught, and will cause this method to return
* <tt>false</tt>. If the handler's <tt>handle</tt> method is successfully
* invoked, then this method will return <tt>true</tt>. This method will
* never throw any sort of exception.
*
* <p> <i>Note:</i> This method is a temporary hack to work around the
* absence of a real API that provides the ability to replace the
* event-dispatch thread. The magic "sun.awt.exception.handler" property
* <i>will be removed</i> in a future release.
*/
Sun 究竟是如何期望你找到这个的,我不知道。
这是一个在 EDT 内外捕获异常的完整示例:
import javax.swing.SwingUtilities;
public class Test {
public static class ExceptionHandler
implements Thread.UncaughtExceptionHandler {
public void handle(Throwable thrown) {
// for EDT exceptions
handleException(Thread.currentThread().getName(), thrown);
}
public void uncaughtException(Thread thread, Throwable thrown) {
// for other uncaught exceptions
handleException(thread.getName(), thrown);
}
protected void handleException(String tname, Throwable thrown) {
System.err.println("Exception on " + tname);
thrown.printStackTrace();
}
}
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler",
ExceptionHandler.class.getName());
// cause an exception on the EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
((Object) null).toString();
}
});
// cause an exception off the EDT
((Object) null).toString();
}
}
应该可以的。
关于java - 如何捕获事件调度线程 (EDT) 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4448523/