考虑以下代码:
Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e) -> {
System.out.println("An exception occurred!");
});
// set the exception handler for the JavaFX application thread
Thread.currentThread().setUncaughtExceptionHandler((Thread t, Throwable e) -> {
System.out.println("An exception occurred!");
});
Task<?> task = new Task() {
@Override
public Void call() throws Exception {
throw new RuntimeException("foobar");
};
};
new Thread(task).start();
Run Code Online (Sandbox Code Playgroud)
如果我们运行代码,运行时异常永远不会触发默认的异常处理程序,而是由任务使用.我找到的唯一抵消这种方法的方法是在task.setOnFailed中重新抛出异常:
task.setOnFailed((WorkerStateEvent t) -> {
throw new RuntimeException(task.getException());
});
Run Code Online (Sandbox Code Playgroud)
既然JavaFX 8现在支持UncaughtExceptionHandler,为什么不将异常传播到异常处理程序?
小智 9
在Task.call()方法内部只是抛出异常并添加ChangeListener到这样的任务:
task.exceptionProperty().addListener((observable, oldValue, newValue) -> {
if(newValue != null) {
Exception ex = (Exception) newValue;
ex.printStackTrace();
}
});
Run Code Online (Sandbox Code Playgroud)
然后,在任务因异常而失败之后,监听器会通知您在执行期间抛出了哪个异常.您可以轻松地交换行ex.printStackTrace();有Alert,如果你是在JavaFX的执行线程.
功能,任务维护exception属性本身.这个想法是,当抛出异常时,任务失败,并且可能会询问抛出了哪个异常.在这方面,Task被认为是一个准批处理作业,在后台运行,并且可能默默地失败.
这反映了一点异步行为; 可以处理异常的地方.不是在start被叫的地方.
可能有点迟,但你可以打印throwable本身:
task.setOnFailed(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent arg0) {
Throwable throwable = task.getException();
throwable.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
无论如何都会抛出异常,但您可以使用它将其显示给用户或进行记录.