Java 未捕获的全局异常处理程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19422366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java uncaught global exception handler
提问by Caballero
I have an application and need to code a custom global uncaught exception handler. I've read all the stackoverflow threads and each one of them is just missing a clear and simple example of how this is to be implemented.
我有一个应用程序,需要编写一个自定义的全局未捕获异常处理程序。我已经阅读了所有的 stackoverflow 线程,并且每个线程都缺少一个清晰而简单的示例,说明如何实现这一点。
Consider this simple following example:
考虑下面这个简单的例子:
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();
}
It throws a standard exception which is just a standard output. How do I implement my own exception which overrides the standard one by something simple as outputing the error into a log file? Obviously the actual application is much larger and we're talking about uncaught exceptions, which is why try/catch blocks is not the option.
它抛出一个标准异常,它只是一个标准输出。我如何实现自己的异常,通过将错误输出到日志文件中这样简单的方法来覆盖标准异常?显然,实际的应用程序要大得多,而且我们谈论的是未捕获的异常,这就是为什么 try/catch 块不是选项的原因。
UPDATE:If you could please answer with a very clear full example, because I found dozens of examples like the one @RamonBoza provided, yet I have no idea how to implement them, which is what this question is all about.
更新:如果你能用一个非常清楚的完整例子来回答,因为我发现了很多例子,比如@RamonBoza 提供的例子,但我不知道如何实现它们,这就是这个问题的全部内容。
UPDATE2:So I've tried to test the only example in the answer below, it obviously doesn't work. I've created a new class file "MyRunnable" and pasted the code in it:
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!");
}
}
Needless to say I get a bunch of errors with this. How can something be outside of class anyway?
不用说,我对此有很多错误。怎么会有课外的东西呢?
UPDATE3:This is the solution that finally works:
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
}
采纳答案by RamonBoza
You can set UncaughtExceptionHandler for the thread controlling the code above:
您可以为控制上述代码的线程设置 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);
}
});
Java docs for UncaughtExceptionHandler-
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
当线程由于未捕获的异常而即将终止时,Java 虚拟机将使用 Thread.getUncaughtExceptionHandler() 查询线程的 UncaughtExceptionHandler 并将调用处理程序的 uncaughtException 方法,将线程和异常作为参数传递
the setUncaughtExceptionHandler is commonly used to free memory or kill threads that the system will not be able to kill, and perhaps, remain zombie.
setUncaughtExceptionHandler 通常用于释放内存或杀死系统无法杀死的线程,并且可能会保持僵尸状态。
A real example:
一个真实的例子:
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!");
}
}
回答by TwoThe
You can try setting your own uncaught Exception handler, however I strongly advise against it. If your application has parts that can potentially break and if that exception is then not properly handled at the location whereyour code breaks, your entire program will malfunction frequently.
您可以尝试设置自己的未捕获的 Exception handler,但我强烈建议不要这样做。如果您的应用程序具有可能会中断的部分,并且如果在代码中断的位置没有正确处理该异常,则您的整个程序将经常出现故障。
回答by Sachin Gorade
You can use UncaughtExceptionHandlerto handle the exception those causes a thread to terminate abruptly. Java doc for UncaughtExceptionHandler -
您可以使用UncaughtExceptionHandler来处理导致线程突然终止的异常。UncaughtExceptionHandler 的 Java 文档 -
Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception. 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
当线程由于未捕获的异常突然终止时调用的处理程序接口。当线程由于未捕获的异常而即将终止时,Java 虚拟机将使用 Thread.getUncaughtExceptionHandler() 查询线程的 UncaughtExceptionHandler 并将调用处理程序的 uncaughtException 方法,将线程和异常作为参数传递
You need to implement this interface and set your implementation of UncaughtExceptionHandler for a thread by using method setUncaughtExceptionHandler. There are two ways you can do this -
您需要实现此接口并使用 setUncaughtExceptionHandler 方法为线程设置 UncaughtExceptionHandler 的实现。有两种方法可以做到这一点 -
- setUncaughtExceptionHandler
- setDefaultUncaughtExceptionHandler
- setUncaughtExceptionHandler
- setDefaultUncaughtExceptionHandler
1) setUncaughtExceptionHandler - This will be a thread specific exception handler. So in case this thread gets terminated by some unhandled exception, this handler will be used.
1) setUncaughtExceptionHandler - 这将是一个线程特定的异常处理程序。因此,如果此线程因某些未处理的异常而终止,将使用此处理程序。
2) setDefaultUncaughtExceptionHandler - This will be a default exception handler in case there is no specific uncaught exception handler for a thread.
2) setDefaultUncaughtExceptionHandler - 如果线程没有特定的未捕获异常处理程序,这将是默认异常处理程序。
Example -
例子 -
class MyExceptionHandler implements UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread arg0, Throwable arg1) {
System.out.println("[DEFAULT EXCEPTION HANDLER] Caught some exception");
}
}
class MyThread extends Thread{
public MyThread() {
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("[THREAD SPECIFIC] My exception handler");
}
});
}
public void run(){
throw new RuntimeException();
}
}
public class Test {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
new MyThread().start();
// current thread does not have a thread specific exception handler
throw new RuntimeException();
}
}