我有一个应用程序,需要编写一个自定义的全局未捕获异常处理程序。我已经阅读了所有的 stackoverflow 线程,但每个线程都缺少一个清晰简单的示例来说明如何实现。
考虑下面这个简单的例子:
public static void log(String msg) throws Exception {
String logPath = "/application/logs/java.log";
Calendar c = new GregorianCalendar();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String now = format.format(c.getTime());
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logPath, true)));
out.println(now + " " + msg);
out.close();
}
它抛出一个标准异常,它只是一个标准输出。如何实现我自己的异常,通过将错误输出到日志文件这样简单的方式覆盖标准异常?显然,实际的应用程序要大得多,而且我们谈论的是未捕获的异常,这就是为什么 try/catch block 不是选项的原因。
更新:如果你能用一个非常清晰的完整例子来回答,因为我发现了几十个像@RamonBoza 提供的例子,但我不知道如何实现它们,这就是这个问题的全部内容。
UPDATE2:所以我尝试测试下面答案中的唯一示例,它显然不起作用。我创建了一个新的类文件“MyRunnable”并将代码粘贴到其中:
package mypackage;
Thread t = new Thread(new MyRunnable());
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
});
t.start();
//outside that class
class MyRunnable implements Runnable(){
public void run(){
throw new RuntimeException("hey you!");
}
}
不用说我得到了一堆错误。怎么会有课外的东西呢?
UPDATE3:这是最终可行的解决方案:
package mypackage;
public class MyClass {
public static void main(String[] args) throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String stacktrace = sw.toString();
System.out.println(stacktrace);
}
});
//main method code
}
//Rest of the methods here
}
最佳答案
您可以为控制上述代码的线程设置UncaughtExceptionHandler:
// t is the parent code thread
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
});
UncaughtExceptionHandler 的 Java 文档-
When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler's uncaughtException method, passing the thread and the exception as arguments
setUncaughtExceptionHandler 通常用于释放内存或杀死系统无法杀死的线程,并且可能保持僵尸状态。
一个真实的例子:
Thread t = new Thread(new MyRunnable());
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
});
t.start();
//outside that class
class MyRunnable implements Runnable(){
public void run(){
throw new RuntimeException("hey you!");
}
}
关于Java 未捕获的全局异常处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19422366/