
第35篇Java异常处理最佳实践系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第34篇Java序列化与反序列化详解 |➡️ 下一篇第36篇选择最适合自己的NIO一探流技术一、核心知识点异常处理的基本原则只捕获能处理的异常不要捕获后什么都不做检查型异常与运行时异常的使用场景try-catch-finally的正确用法try-with-resources自动关闭资源自定义异常的规范异常链与异常包装日志记录的最佳实践二、通俗讲解1分钟开心学1. 异常处理的核心思想只捕获你能处理的异常。捕获后要做出有意义的响应记录日志、返回默认值、重试、包装后重新抛出。2. 检查型异常 vs 运行时异常检查型异常如IOException调用者必须处理或声明抛出代表可恢复的外部错误文件不存在、网络中断。运行时异常如NullPointerException不强制处理代表编程错误参数校验不足、数组越界应当通过改进代码避免。3. try-with-resources自动关闭实现了AutoCloseable接口的资源文件、网络连接、数据库连接避免finally中手动关闭的繁琐。4. 异常链当你在一个异常中包装另一个异常时可以保留原始异常信息便于排查。5. 日志记录捕获异常后务必记录日志使用log.error(消息, e)不要只打印e.printStackTrace()在正式环境可能不可见。6. 自定义异常继承Exception检查型或RuntimeException运行时。提供多个构造方法无参、带消息、带消息原异常。生活类比异常处理就像开车遇到故障。能自己修的小毛病运行时异常就用工具修好改进代码。大问题检查型异常需要呼叫救援try-catch然后记录事故日志。三、实操代码案例 场景说明场景读取配置文件处理文件不存在的异常并确保流被正确关闭。importjava.io.*;importjava.util.Properties;importjava.util.logging.*;publicclassExceptionBestPractice{privatestaticfinalLoggerloggerLogger.getLogger(ExceptionDemo);// 1. 正确使用 try-with-resources 自动关闭publicstaticStringreadFirstLine(Stringpath){try(BufferedReaderbrnewBufferedReader(newFileReader(path))){returnbr.readLine();}catch(IOExceptione){// 记录日志不要吞掉异常logger.log(Level.SEVERE,读取文件失败: path,e);returnnull;// 或抛出运行时异常}}// 2. 异常包装与链publicstaticPropertiesloadConfig(Stringpath)throwsConfigException{try(InputStreaminnewFileInputStream(path)){PropertiespropsnewProperties();props.load(in);returnprops;}catch(IOExceptione){// 包装为自定义异常保留原始原因thrownewConfigException(加载配置失败: path,e);}}// 3. 运行时异常用于参数校验publicstaticvoidsetAge(intage){if(age0||age150){thrownewIllegalArgumentException(年龄必须在0~150之间实际: age);}// 正常处理}// 4. 不要空 catchpublicstaticvoidbadPractice(){try{inta10/0;}catch(ArithmeticExceptione){// 什么都不做问题被隐藏了这是最坏的实践}}publicstaticvoidmain(String[]args){StringlinereadFirstLine(nonexist.txt);System.out.println(读取结果: line);try{PropertiespropsloadConfig(config.properties);}catch(ConfigExceptione){e.printStackTrace();// 正式环境用 logger}try{setAge(200);}catch(IllegalArgumentExceptione){System.err.println(e.getMessage());}}}// 自定义检查型异常classConfigExceptionextendsException{publicConfigException(Stringmessage,Throwablecause){super(message,cause);}publicConfigException(Stringmessage){super(message);}}四、避坑要点错误/误区后果正确做法捕获异常后什么都不做空 catch掩盖问题难以排查至少记录日志在finally中关闭资源但不处理异常如果关闭失败异常被吞没使用try-with-resources抛出检查型异常但调用者无法处理传递上层导致处处throws考虑包装为运行时异常在循环中catch异常性能差且可能陷入无限循环循环外处理或使用重试策略日志只打印e.getMessage()丢失栈轨迹使用log.error(msg, e)打印完整堆栈五、面试高频考点Q1什么时候应该捕获检查型异常什么时候应该向上抛出如果当前层能恢复或做出合理响应如重试、使用默认值则捕获否则向上抛出让上层处理。对于框架代码常包装为运行时异常抛出。Q2try-with-resources的原理是什么实现了AutoCloseable的资源可以在try括号中声明编译后生成finally块调用close()并处理异常抑制addSuppressed。Q3如何正确记录异常日志使用日志框架如java.util.logging、Log4j、SLF4J记录完整堆栈logger.error(操作失败, e);不要只记录e.getMessage()。六、练习题代码改错指出下面代码的问题并改正。try{FileInputStreamfisnewFileInputStream(test.txt);fis.read();fis.close();}catch(IOExceptione){e.printStackTrace();}设计写一个方法divide(int a, int b)如果 b 为 0抛出自定义运行时异常DivideByZeroException。场景你正在开发一个网络请求库当网络超时时应如何处理异常 你的学习进度当前第35篇 / 共44篇 ·第五阶段工具类、异常最佳实践、序列化第32~35篇✅ 已完成第1~34篇 正在学第35篇⏳ 待学习第36~44篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 本专栏每篇都包含避坑表 面试高频考点 练习题。每天30分钟100天拿offer 下一篇文章预告《第36篇选择最适合自己的NIO一探流技术》内容简介BIO/NIO/AIO区别、流体系字节/字符/缓冲/转换、NIO核心组件Channel/Buffer/Selector、零拷贝。 学完这篇你将掌握Java I/O的全貌并能根据场景选择合适的I/O模型。《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送