本文目录导读:

在Java中全局捕获异常主要有以下几种方式,下面按常见场景详细介绍:
Web应用全局异常处理(Spring Boot)
使用@ControllerAdvice + @ExceptionHandler
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理所有未捕获的异常
@ExceptionHandler(Exception.class)
public Result<String> handleException(Exception e) {
// 记录日志
log.error("系统异常", e);
return Result.error(500, "系统繁忙,请稍后重试");
}
// 处理特定异常
@ExceptionHandler(IllegalArgumentException.class)
public Result<String> handleIllegalArgument(IllegalArgumentException e) {
return Result.error(400, e.getMessage());
}
// 处理业务异常
@ExceptionHandler(BusinessException.class)
public Result<String> handleBusinessException(BusinessException e) {
return Result.error(e.getCode(), e.getMessage());
}
}
自定义业务异常
public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
}
Java桌面应用全局异常捕获
使用UncaughtExceptionHandler
public class GlobalExceptionCatcher {
public static void main(String[] args) {
// 设置全局异常处理器
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
// 记录日志
System.err.println("线程 " + t.getName() + " 发生未捕获异常:");
e.printStackTrace();
// 显示友好提示
JOptionPane.showMessageDialog(null,
"程序发生异常,请检查日志文件",
"系统异常",
JOptionPane.ERROR_MESSAGE);
}
}
);
// 启动应用程序
SwingUtilities.invokeLater(() -> {
new MyApplication().start();
});
}
}
完整的Swing应用示例
public class SwingExceptionHandler {
public static void main(String[] args) {
// 1. 设置线程异常处理器
Thread.setDefaultUncaughtExceptionHandler(
(thread, throwable) -> handleException(throwable)
);
// 2. 设置AWT事件异常处理器
System.setProperty("sun.awt.exception.handler",
AWTExceptionHandler.class.getName());
// 3. 启动应用
EventQueue.invokeLater(() -> {
try {
new MyFrame().setVisible(true);
} catch (Exception e) {
handleException(e);
}
});
}
private static void handleException(Throwable e) {
// 记录异常到文件
try (FileWriter fw = new FileWriter("error.log", true);
PrintWriter pw = new PrintWriter(fw)) {
e.printStackTrace(pw);
} catch (IOException ex) {
ex.printStackTrace();
}
// 显示友好提示
JOptionPane.showMessageDialog(null,
"系统出现异常,请查看error.log文件了解详情",
"错误",
JOptionPane.ERROR_MESSAGE);
}
}
// AWT异常处理器
public class AWTExceptionHandler {
public void handle(Throwable throwable) {
SwingExceptionHandler.handleException(throwable);
}
}
多线程环境下的全局异常捕获
线程池异常处理
public class ThreadPoolExceptionHandler {
public static void main(String[] args) {
// 创建自定义线程工厂
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("线程 " + thread.getName() +
" 发生异常: " + throwable.getMessage());
}).build();
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(5, threadFactory);
// 或者直接设置
ThreadPoolExecutor pool = new ThreadPoolExecutor(
5, 10, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler(
(thread, throwable) -> {
System.err.println("异常处理: " +
throwable.getMessage());
}
);
return t;
}
}
);
}
}
CompletableFuture异常处理
public class CompletableFutureExceptionHandler {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("异步任务异常");
}
return "成功";
})
.exceptionally(throwable -> {
System.err.println("捕获异常: " + throwable.getMessage());
return "默认值";
})
.handle((result, throwable) -> {
if (throwable != null) {
System.err.println("异常处理: " + throwable.getMessage());
return "处理异常";
}
return result;
});
}
}
Filter方式全局异常捕获(Web应用)
@WebFilter("/*")
public class ExceptionFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
} catch (Exception e) {
// 全局异常处理
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// 记录日志
log.error("请求 {} 发生异常", req.getRequestURI(), e);
// 返回统一错误响应
resp.setContentType("application/json;charset=UTF-8");
resp.getWriter().write(JSON.toJSONString(
Result.error(500, "系统异常")
));
}
}
}
最佳实践建议
组合使用多种捕获方式
@Configuration
public class ExceptionConfig {
// 1. 全局异常处理
@Bean
public GlobalExceptionHandler globalExceptionHandler() {
return new GlobalExceptionHandler();
}
// 2. 线程异常处理器
@PostConstruct
public void initThreadExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(
(thread, throwable) -> {
log.error("线程 [{}] 发生未捕获异常",
thread.getName(), throwable);
// 发送告警通知
alertService.sendAlert(throwable);
}
);
}
// 3. 自定义异常处理策略
@Bean
public ExceptionHandler exceptionHandler() {
return new SimpleMappingExceptionResolver() {{
setDefaultErrorView("error");
setExceptionAttribute("exception");
setDefaultStatusCode(500);
// 特定异常映射
setExceptionMappings(new Properties() {{
put("java.lang.IllegalArgumentException", "error-400");
put("com.example.BusinessException", "error-biz");
}});
}};
}
}
异常处理注意事项
- 不要过度捕获:只捕获确实需要全局处理的异常
- 区分异常类型:业务异常、系统异常、第三方异常应分开处理
- 保留原始异常:在包装异常时保留原始异常信息
- 日志记录:所有全局捕获的异常都要记录日志
- 友好提示:用户界面显示友好的错误信息,不要暴露技术细节
选择哪种方式取决于应用类型和需求,通常Web应用推荐使用@ControllerAdvice,桌面应用使用UncaughtExceptionHandler。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播