怎么做出有品牌感的网站门户网站营销
怎么做出有品牌感的网站,门户网站营销,asp的网站空间,网站做ddns解析Java 的异常#xff08;Exception#xff09;体系是语言最核心的工程能力之一#xff1a;它决定了错误如何表达、如何传播、如何被定位与恢复。写出“可维护、可诊断、可扩展”的 Java 代码#xff0c;异常设计和处理能力往往是分水岭。本文从异常体系结构讲起#xff0c;…Java 的异常Exception体系是语言最核心的工程能力之一它决定了错误如何表达、如何传播、如何被定位与恢复。写出“可维护、可诊断、可扩展”的 Java 代码异常设计和处理能力往往是分水岭。本文从异常体系结构讲起覆盖Checked/Unchecked 的本质差异、try-catch-finally 细节、try-with-resources、异常链、常见反模式、业务异常设计、日志与统一处理等高频面试 实战内容。1. 异常是什么为什么需要异常机制异常Throwable本质是程序运行过程中出现了非预期状态需要一种机制把“错误”从局部传递到上层并携带足够的诊断信息类型、堆栈、消息、原因。相比返回错误码异常机制的优势能携带调用栈定位成本低支持分类类型系统驱动处理策略支持异常链保留根因强制/约束处理Checked 异常2. Java 异常体系总览Throwable 树Java 异常顶层父类java.lang.Throwable主要分两大分支Error严重问题通常不可恢复如 JVM 内存溢出、类加载错误。一般不捕获或不做业务兜底恢复。Exception可处理的异常。Exception 下面再分Checked Exception受检异常必须显式处理try-catch 或 throwsUnchecked Exception非受检异常RuntimeException及其子类编译器不强制处理记忆口诀Error 不管Exception 要管RuntimeException 不强制管。3. Checked vs Unchecked本质区别与工程取舍3.1 Checked受检异常典型IOException,SQLException特点编译器强制处理不处理就编译不过适合“调用方可能合理恢复”的场景如读文件失败可以换路径/重试/降级代价在层层调用中会导致“throws 传染”容易出现大量样板代码try-catch/throws3.2 Unchecked非受检异常典型NullPointerException,IllegalArgumentException,IndexOutOfBoundsException特点不强制处理更适合编程错误、参数非法、状态不一致等“应当修代码而非恢复”的问题3.3 实战建议重要业务校验失败、用户输入错误、业务规则不满足通常用自定义运行时异常Unchecked外部依赖失败IO、网络、DB且调用方确实可恢复可以保留 Checked或在边界层转为业务异常在服务端工程Spring Boot中更常见的实践是底层异常统一包装为业务运行时异常 全局异常处理便于统一返回、统一日志、减少 throws 传染4. try-catch-finally 语义细节面试高频4.1 finally 一定会执行吗一般情况下会执行无论是否抛异常、是否 return。但以下情况 finally 可能不执行System.exit()直接终止 JVMJVM 崩溃如致命错误线程被强制杀死极端情况4.2 catch 顺序从子类到父类否则会编译错误父类捕获会吞掉子类分支。try { // ... } catch (NullPointerException e) { // 子类 } catch (RuntimeException e) { // 父类 }4.3 finally 里不要 return / throw非常重要finally 里的 return 会覆盖try/catch 的返回值或异常导致排查地狱。public int bad() { try { return 1; } finally { return 2; // 覆盖 try 的返回 } }5. try-with-resources资源关闭的最佳方式JDK 7 引入专为实现AutoCloseable的资源流、连接、文件句柄等设计自动 close且能正确处理 close 时的异常抑制suppressed。try (BufferedReader br new BufferedReader(new FileReader(path))) { return br.readLine(); } catch (IOException e) { throw new RuntimeException(读取文件失败, e); }5.1 suppressed 异常是什么当 try 块抛异常close 又抛异常close 异常会被记录为suppressed主异常仍保留利于排查。Throwable[] suppressed e.getSuppressed();6. 异常链Cause与“保留根因”原则真实系统里异常往往层层包装。最佳实践包装异常时一定要把 cause 传进去。正确catch (IOException e) { throw new BizException(文件服务不可用, e); }错误丢失堆栈与根因catch (IOException e) { throw new BizException(文件服务不可用); }定位问题时最值钱的是原始异常类型 堆栈 触发点。7. 自定义业务异常高质量设计模板7.1 为什么要自定义业务异常把“可预期的业务失败”与“系统故障”区分开便于统一返回码、统一错误信息便于全局处理与统计监控7.2 推荐结构错误码 可读消息 可选上下文public class BizException extends RuntimeException { private final String code; public BizException(String code, String message) { super(message); this.code code; } public BizException(String code, String message, Throwable cause) { super(message, cause); this.code code; } public String getCode() { return code; } }进一步优化可选code 用枚举统一管理message 走国际化i18n附带 context如订单号、用户 id但注意隐私与安全8. Spring/Spring Boot 项目中的统一异常处理常用范式常见做法使用RestControllerAdviceExceptionHandler统一返回结构。RestControllerAdvice public class GlobalExceptionHandler { ExceptionHandler(BizException.class) public ResponseEntity? handleBiz(BizException e) { // 业务异常可控不打 full stack 或按需打印 return ResponseEntity.badRequest().body( Map.of(code, e.getCode(), msg, e.getMessage()) ); } ExceptionHandler(Exception.class) public ResponseEntity? handleOther(Exception e) { // 系统异常必须记录堆栈 // log.error(系统异常, e); return ResponseEntity.status(500).body( Map.of(code, SYSTEM_ERROR, msg, 系统繁忙请稍后再试) ); } }工程建议业务异常一般不需要打印成 ERROR 大堆栈防止日志噪音可按 warn/info或打印摘要系统异常必须带堆栈 traceId链路追踪返回给用户的信息要“友好且不泄露内部细节”9. 异常处理的经典反模式高频踩坑9.1 catch (Exception) 然后什么都不做吞异常try { doSomething(); } catch (Exception e) { // ignore }危害问题静默线上数据错了你都不知道。9.2 用异常做正常流程控制比如用try/catch判断 map 是否有 key或用捕获 NPE 当作 if。异常很贵构造堆栈开销大而且可读性差。9.3 只打印 e.getMessage() 不打印堆栈堆栈才是定位关键。正确log.error(xxx, e);错误log.error(e.getMessage());9.4 捕获后丢失 cause见前文异常链。9.5 finally 里做关键业务逻辑finally 适合做资源释放、清理动作。关键逻辑放 finally 容易被覆盖/吞异常/难维护。10. 常见运行时异常速查附触发原因与建议NullPointerException对象为空仍调用方法/字段建议参数校验、Optional慎用、合理默认值、提前失败IllegalArgumentException方法参数非法建议对外接口优先抛它或 BizExceptionIllegalStateException对象状态不对建议状态机/流程控制要清晰ClassCastException类型转换错误建议泛型、instanceof、避免 raw typeNumberFormatException字符串转数字失败建议输入校验、异常转换为业务提示IndexOutOfBoundsException索引越界建议边界判断11. 如何写出“可诊断”的异常信息日志与消息技巧高质量异常信息 发生了什么 为什么 影响什么 关键上下文示例“下单失败”“下单失败库存不足skuxxx, need3, left1, orderIdxxx”注意不要把敏感信息写入异常 message 和日志如密码、token、完整身份证号上下文信息建议通过结构化日志字段traceId、userId、orderId输出12. 一套推荐的异常分层策略适合大多数后端项目按层思考DAO/Client 层DB/HTTP/IO抛出原始异常或封装成基础设施异常Service 层将外部异常转换为业务可理解的 BizException保留 causeController/网关层统一异常处理 返回统一格式 统一日志策略目标业务代码不被大量 try-catch 污染异常含义清晰、定位方便用户返回安全、可控13. 总结建议收藏的要点清单Throwable 分 Error/ExceptionException 分 Checked/Unchecked受检异常强制处理非受检异常更适合编程错误与业务失败finally 不要 return/throwcatch 顺序从子类到父类资源关闭优先用 try-with-resources包装异常一定传 cause保留根因与堆栈业务异常建议错误码 message 可选上下文Spring 常用RestControllerAdvice 做统一异常处理避免吞异常、避免用异常做流程控制、日志要打印堆栈异常信息要可诊断但不要泄露敏感信息