Java异常处理与堆栈跟踪详解
立即解锁
发布时间: 2025-08-18 02:21:37 阅读量: 2 订阅数: 12 

### Java异常处理与堆栈跟踪详解
#### 1. AWTExceptionHandler类
在Java的GUI应用程序中,`AWTExceptionHandler` 类起着至关重要的作用,它是一个通用的顶级异常处理程序,属于 `ThreadGroup` 的子类。该类可以与 `awt.threadgroup` 或 `sun.awt.exception.handler` 系统属性配合使用,但不适用于非GUI应用程序,因为其初始化方法 `init(JFrame frame, Logger logger, Redirect redirect)` 要求传入一个 `JFrame` 对象。
##### 1.1 单例模式实现
尽管使用了公共构造函数(这是核心反射API的要求),`AWTExceptionHandler` 仍然是单例设计模式的一个示例。以下是其构造函数和获取实例的方法代码:
```java
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.logging.Handler;
import java.util.logging.FileHandler;
import java.util.logging.MemoryHandler;
public class AWTExceptionHandler extends ThreadGroup
implements Redirect.Constants {
private static String separator = System.getProperty
("line.separator");
private static AWTExceptionHandler instance = null;
private boolean initialized = false;
private JFrame frame;
private Logger logger;
private Redirect redirect;
private String encoding;
private PrintStream sysOut;
private PrintStream sysErr;
public AWTExceptionHandler() {
super("dummy");
if (instance != null)
throw new IllegalStateException(
"AWTExceptionHandler already exists");
instance = this;
}
public AWTExceptionHandler(String name) {
super(name);
if (instance != null)
throw new IllegalStateException(
"AWTExceptionHandler already exists");
instance = this;
}
public static AWTExceptionHandler getInstance() {
if (instance == null)
throw new NullPointerException(
"AWTExceptionHandler has not been instantiated");
return instance;
}
}
```
##### 1.2 重定向标准输出和错误流
在GUI应用程序中,将标准输出和标准错误重定向到日志文件非常重要,原因如下:
- 对于没有控制台窗口的GUI应用程序(如使用 `javaw` 启动器启动的应用程序,包括Java Web Start),标准输出和标准错误是无用的。
- 即使你不向标准输出或标准错误写入内容,`java.awt` 和 `javax.swing` 包中的许多核心API类也会经常捕获异常并将重要的诊断信息写入标准错误。
`AWTExceptionHandler` 类通过将标准错误和标准输出重定向到 `ByteArrayOutputStream` 子类并覆盖 `flush()` 方法来实现这一功能。诊断消息根据写入的流分别使用 `Level.WARNING` 或 `Level.INFO` 进行记录。以下是初始化和重定向的代码:
```java
public synchronized void init(JFrame frame,
Logger logger,
Redirect redirect) {
if (logger == null)
throw new IllegalArgumentException("logger is null");
if (redirect == null)
throw new IllegalArgumentException("redirect is null");
instance.frame = frame;
instance.logger = logger;
instance.redirect = redirect;
initialized = true;
Handler[] handlers = logger.getHandlers();
for (int i=0; i<handlers.length; i++) {
if (handlers[i].getEncoding() != null) {
encoding = handlers[i].getEncoding();
if (handlers[i] instanceof FileHandler) {
break;
}
}
}
if (encoding == null) {
sysOut = new PrintStream(new StandardOutputStream(),
true);
sysErr = new PrintStream(new StandardErrorStream(),
true);
} else try {
sysOut = new PrintStream(new StandardOutputStream(),
true,
encoding);
sysErr = new PrintStream(new StandardErrorStream(),
true,
encoding);
} catch(UnsupportedEncodingException e) {assert false;}
switch(redirect.intValue()) {
case NEITHER:
break;
case STANDARD_OUTPUT:
System.setOut(sysOut);
break;
case STANDARD_ERROR:
System.setErr(sysErr);
break;
case BOTH:
System.setOut(sysOut);
System.setErr(sysErr);
default:
assert false;
}
}
```
##### 1.3 异常处理方法
当捕获到未捕获的异常时,`AWTExceptionHandler` 类会调用 `handle` 方法进行处理。该方法会记录详细的异常信息,并弹出一个错误对话框通知用户。以下是 `handle` 方法的代码:
```java
public void uncaughtException(Thread t, Throwable e) {
handle(e);
}
public void handle(Throwable e) {
if (!initialized)
throw new IllegalStateException(
"AWTExceptionHandler has not been initialized");
new UncaughtException(logger, e).logVerbose();
Handler[] handlers = logger.getHandlers();
for (int i=0; i<handlers.length; i++) {
Handler handler = handlers[i];
if (handler instanceof MemoryHandler)
((MemoryHandler)handler).push();
}
if (e instanceof ThreadDeath) {
return;
}
String message =
"An unknown error has occured and" + separator +
"the application must be closed." + separator +
"Diagnostic information has been" + separator +
"written to a log file. Please inform" + separator +
"your System Administrator.";
JOptionPane.showMessageDialog(null, message,
"Fatal Error",
JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
```
#### 2. UncaughtException类
`UncaughtException` 类的主要作用是将尽可能多的失败信息写入日志文件。构造函数确保至少将堆栈跟踪信息保存到日志文件中。以下是该类的代码:
```java
import java.io.*;
import java.util.*;
import java.util.logging.*;
public class UncaughtException {
private Logger logger;
private Throwable uncaughtException;
private static CharArrayWriter message =
new CharArrayWriter();
private static PrintWriter log = new PrintWriter(
new BufferedWriter(message));
```
0
0
复制全文
相关推荐










