每个Java程序员都要处理异常,异常处理在应用程序中起着重要的作用。在Java世界中,处理异常看上去不是那么简单,不仅仅是在异常发生的地方,优雅的报告异常。
使用ThreadGroup处理异常
ThreadGroup类中在这个时候大部分方法已经作废了,但是该类还是很有用的。ThreadGroup类有一个方法uncaughtException(Thread,Throwable),意思是:当线程组中的线程因为异常而终止时,Java虚拟机调用该方法。这样你可以考虑继承ThreadGroup类来处理你应用中没有捕获的异常。
public class AppSpecificThreadGroup extends ThreadGroup {
public void uncaughtException(Thread, Throwable) {
// app specific error handling here
// ex: if fatal, release resources
// show user dialog
}
}
这样在你的应用启动的时候,把你的线程加入到线程组(Thread group)中。
public class ApplicationMain {
public static void main(String[] args) {
Runnable r = new ApplicationStarter(args);
ThreadGroup g = new AppSpecificThreadGroup();
Thread t = new Thread(g, r);
t.start();
}
private static void doStart(String[] args) {
// start application here...
}
private static class ApplicationStarter {
private String[] args;
ApplicationStarter(String[] args) {
this.args = args;
}
public void run() {
doStart(args);
}
}
}
使用Java5的Thread.UncaughtExceptionHandler
当认识到ThreadGroup.uncaughtException(Thread,Throwable)方法的巨大作用时,Sun团队在Java5版本站中增强了未捕获的异常处理的功能,引入了Thread.UncaughtExceptionHandler接口,另外这个接口引入了两个新的”Check points”用于处理异常。Thread类有两个属性-uncaughtExceptionHandler和defaultUncaughtExceptionHandler,它们有相应的get/set方法。但是这两个方法是不同的。让我们看看处理异常的过程。
n 使用uncaughtExceptionHandler为当前线程处理异常。
n 如果uncaughtExceptionHandler为空(null),使用线程组(如果用户没有显示设置,线程组是uncaughtExceptionHandler的默认实现)。
n 如果线程组是默认的实现,但是不是根线程组,将把错误处理委派给父线程组。
n 如果线程组是默认的实现,并且是根线程组,将使用线程(Thread)类上设置的defaultUncaughtExceptionHandler方法。
n 如果在线程类没有设置defaultUncaughtExceptionHandler,将调用Java5之前的ThreadGroup类中的未捕获异常方法。
实现Thread.UncaughtExceptionHandler接口看起来也像上面实现ThreadGroup接口。
public class AppSpecificExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread, Throwable) {
// app specific error handling here
// ex: if fatal, release resources
// show user dialog
}
}
在应用程序中插入如下:
public class ApplicationMain {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new AppSpecificExceptionHandler());
}
}
Swing异常处理实现
许多人没有注意到现有的JOptionPanel类,该类中有许多的优美的弹出对话框的静态方法(showOptionDialog,showConfirmDialog,showInputDialog,和showMessageDialog),这些方法接受的参数不仅仅是字符串。这些静态方法(也包括JOptionPanel构造函数)都是接受一个Object作为参数的的。下面是一个实现该类的核心代码:
public class ErrorDialog {
public ErrorDialog() {
super();
}
public static void showQuickErrorDialog(JFrame parent, Exception e) {
final JTextArea textArea = new JTextArea();
textArea.setFont(new Font("Sans-Serif", Font.PLAIN, 10));
textArea.setEditable(false);
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
textArea.setText(writer.toString());
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(350, 150));
JOptionPane.showMessageDialog(parent, scrollPane,
"An Error Has Occurred", JOptionPane.ERROR_MESSAGE);
}
}
在程序中的一个例图如下: