Java异常处理中小厂面试通关指南2小时速通 | 面试必备 | 实战导向一、异常体系全景图1.1 继承关系Throwable (所有异常的根类) ├── Error (系统级错误不可恢复) │ ├── OutOfMemoryError │ ├── StackOverflowError │ └── VirtualMachineError └── Exception (程序异常可处理) ├── RuntimeException (运行时异常非受检) │ ├── NullPointerException │ ├── IllegalArgumentException │ ├── ArrayIndexOutOfBoundsException │ ├── ClassCastException │ ├── NumberFormatException │ └── ArithmeticException └── 其他Exception (编译时异常受检) ├── IOException ├── SQLException ├── ClassNotFoundException └── InterruptedException1.2 两大分类对比特性编译时异常 (Checked)运行时异常 (Unchecked)继承关系Exception (非RuntimeException)RuntimeException编译要求必须显式处理 (try-catch/throws)无强制要求发生时机外部因素 (IO、网络、数据库)代码逻辑问题处理建议必须处理可提前规避面试重点了解常用类型高频考点 ⭐⭐⭐二、异常核心概念2.1 四大关键字try-catch捕获并处理异常try{// 可能抛出异常的代码}catch(SpecificExceptione){// 处理特定异常}catch(Exceptione){// 处理其他异常放最后}throws声明方法可能抛出的异常publicvoidreadFile(Stringpath)throwsIOException{// 方法实现}throw手动抛出异常对象if(age0){thrownewIllegalArgumentException(年龄不能为负数);}finally无论如何都会执行的代码块try{// 业务代码}finally{// 资源清理关闭文件、释放连接等// ⚠️ 严禁在此写 return}2.2 异常处理流程程序执行 ↓ 遇到异常 ↓ JVM创建异常对象 ↓ 是否有try-catch ├─ 是 → 匹配catch块 → 执行finally → 继续执行 └─ 否 → 向上抛出 → 最终到main → 程序终止三、常见异常速查表3.1 运行时异常 (重点掌握)异常类触发场景代码示例解决方案NullPointerException调用null对象的方法/属性String s null;s.length();判空if (s ! null)IllegalArgumentException方法参数不合法setAge(-1)参数校验 抛异常ArrayIndexOutOfBoundsException数组下标越界arr[10](数组长度5)校验if (i arr.length)NumberFormatException字符串转数字失败Integer.parseInt(abc)try-catch 或正则预校验ClassCastException类型强转失败(Dog) animal先用instanceof判断ArithmeticException数学运算错误10 / 0校验除数不为0IndexOutOfBoundsException集合索引越界list.get(100)校验索引范围ConcurrentModificationException并发修改集合遍历时删除元素使用迭代器删除3.2 编译时异常 (了解即可)异常类触发场景处理方式IOException文件读写、网络IO失败try-catch 或 throwsSQLException数据库操作失败统一捕获处理ClassNotFoundException反射找不到类try-catchInterruptedException线程中断恢复中断状态四、异常处理最佳实践4.1 业务场景对应规范场景推荐做法示例参数校验失败抛自定义运行时异常throw new ParamException(用户名不能为空)业务逻辑违规抛自定义业务异常throw new BusinessException(余额不足)文件/IO操作捕获IOExceptiontry { ... } catch (IOException e)数据库操作捕获SQLException统一异常处理器代码逻辑疏漏提前规避判空、范围校验4.2 自定义异常模板/** * 业务异常基类 */publicclassBusinessExceptionextendsRuntimeException{privateintcode;privateStringmessage;publicBusinessException(Stringmessage){super(message);this.code500;this.messagemessage;}publicBusinessException(intcode,Stringmessage){super(message);this.codecode;this.messagemessage;}publicintgetCode(){returncode;}OverridepublicStringgetMessage(){returnmessage;}}4.3 异常处理原则✅应该做的捕获具体异常而非Exception记录异常日志包含堆栈信息给用户友好的错误提示在finally中释放资源自定义异常继承RuntimeException❌不应该做的空catch块吞掉异常finally中写return过度使用异常正常逻辑用if判断捕获Error系统级错误异常信息暴露敏感数据五、面试手撕真题真题1字符串转整数基础必考题目要求实现stringToInt(String s)方法处理 null、空字符串、非数字字符串异常时返回0并打印错误信息禁止空catch块标准答案publicclassStringConverter{publicintstringToInt(Strings){// 1. 处理nullif(snull){System.out.println(错误字符串为null);return0;}// 2. 处理空字符串if(s.trim().isEmpty()){System.out.println(错误字符串为空);return0;}// 3. 尝试转换try{returnInteger.parseInt(s);}catch(NumberFormatExceptione){System.out.println(错误s 无法转为数字);return0;}}// 测试publicstaticvoidmain(String[]args){StringConverterconverternewStringConverter();System.out.println(converter.stringToInt(123));// 123System.out.println(converter.stringToInt(abc));// 0System.out.println(converter.stringToInt(null));// 0System.out.println(converter.stringToInt());// 0}}考点分析边界条件处理null、空字符串具体异常捕获NumberFormatException异常信息输出返回默认值真题2自定义参数校验异常高频题目要求自定义ParamValidException继承RuntimeException包含 code异常码和 msg异常信息实现用户注册校验用户名≥6位密码≥8位标准答案/** * 自定义参数校验异常 */classParamValidExceptionextendsRuntimeException{privateintcode;privateStringmsg;publicParamValidException(Stringmsg){super(msg);this.code400;this.msgmsg;}publicParamValidException(intcode,Stringmsg){super(msg);this.codecode;this.msgmsg;}publicintgetCode(){returncode;}publicStringgetMsg(){returnmsg;}}/** * 用户注册服务 */publicclassUserService{publicvoidregister(Stringusername,Stringpassword){// 用户名校验if(usernamenull||username.length()6){thrownewParamValidException(400,用户名长度不能小于6位);}// 密码校验if(passwordnull||password.length()8){thrownewParamValidException(400,密码长度不能小于8位);}System.out.println(注册成功username);}// 测试publicstaticvoidmain(String[]args){UserServiceservicenewUserService();try{service.register(user,12345678);// 用户名太短}catch(ParamValidExceptione){System.out.println(异常码e.getCode());System.out.println(异常信息e.getMsg());}try{service.register(username,123);// 密码太短}catch(ParamValidExceptione){System.out.println(异常码e.getCode());System.out.println(异常信息e.getMsg());}service.register(username,12345678);// 成功}}考点分析自定义异常类设计继承RuntimeException无需throws构造方法重载业务参数校验异常信息封装真题3try-catch-finally执行顺序坑点题题目分析以下代码的执行顺序和返回值publicclassFinallyTest{publicstaticinttest(){intnum10;try{System.out.println(1. try块执行);numnum/0;// 抛出异常returnnum;}catch(ArithmeticExceptione){System.out.println(2. catch块执行);num20;returnnum;}finally{System.out.println(3. finally块执行);num30;returnnum;// ⚠️ 问题代码}}publicstaticvoidmain(String[]args){System.out.println(最终返回值test());}}输出结果1. try块执行 2. catch块执行 3. finally块执行 最终返回值30问题分析try块抛出异常跳转到catchcatch块准备返回20但finally必须先执行finally块执行并返回30覆盖了catch的返回值严重问题finally中的return会覆盖正常返回值正确写法publicstaticinttest(){intnum10;try{System.out.println(1. try块执行);numnum/0;returnnum;}catch(ArithmeticExceptione){System.out.println(2. catch块执行);num20;returnnum;}finally{System.out.println(3. finally块执行);num30;// 只修改变量不return// 资源清理代码}}// 此时返回值为20正确考点分析try-catch-finally执行顺序finally中return的坑异常处理流程代码规范六、面试高频问答Q1Exception和Error的区别答Exception程序异常可预见可处理如空指针、IO异常Error系统级错误不可恢复如内存溢出、栈溢出关键区别Exception应该捕获处理Error无需处理程序无法恢复Q2运行时异常和编译时异常的区别答编译时异常继承Exception但非RuntimeException编译期必须处理运行时异常继承RuntimeException编译期无强制要求使用场景编译时异常用于外部因素IO、网络运行时异常用于代码逻辑问题Q3throw和throws的区别答throw方法内部手动抛出异常对象throw new Exception()throws方法签名声明可能抛出的异常void method() throws Exception记忆技巧throw抛对象throws声明类型Q4finally一定会执行吗答不一定以下情况不执行JVM退出System.exit()守护线程中主线程结束死循环或死锁断电、进程被杀正常情况下即使try/catch中有returnfinally也会执行Q5如何自定义异常答// 1. 继承RuntimeException推荐或ExceptionpublicclassCustomExceptionextendsRuntimeException{privateintcode;// 2. 提供构造方法publicCustomException(Stringmessage){super(message);}publicCustomException(intcode,Stringmessage){super(message);this.codecode;}// 3. 提供getter方法publicintgetCode(){returncode;}}Q6try-catch会影响性能吗答正常流程性能影响极小可忽略异常抛出创建异常对象、填充堆栈有一定开销建议不要用异常控制正常业务流程用if判断Q7多个catch块的顺序有要求吗答有要求必须从子类到父类排列try{// 代码}catch(FileNotFoundExceptione){// 子类// 处理}catch(IOExceptione){// 父类// 处理}catch(Exceptione){// 最父类// 处理}原因Java按顺序匹配catch块父类会捕获所有子类异常七、避坑指南坑点1空catch块// ❌ 错误吞掉异常try{// 代码}catch(Exceptione){// 什么都不做}// ✅ 正确至少打印日志try{// 代码}catch(Exceptione){e.printStackTrace();// 或使用日志框架log.error(操作失败,e);}坑点2finally中return// ❌ 错误覆盖正常返回值try{return1;}finally{return2;// 最终返回2隐藏了try的返回}// ✅ 正确finally只做清理try{return1;}finally{// 关闭资源connection.close();}坑点3捕获Exception// ❌ 错误无法区分异常类型try{// 代码}catch(Exceptione){// 所有异常都这样处理}// ✅ 正确捕获具体异常try{// 代码}catch(IOExceptione){// IO异常处理}catch(SQLExceptione){// 数据库异常处理}坑点4资源未关闭// ❌ 错误异常时资源泄漏FileInputStreamfisnewFileInputStream(file.txt);try{// 读取文件}catch(IOExceptione){e.printStackTrace();}// 如果try中抛异常fis未关闭// ✅ 正确使用try-with-resourcestry(FileInputStreamfisnewFileInputStream(file.txt)){// 读取文件}catch(IOExceptione){e.printStackTrace();}// 自动关闭资源坑点5异常信息暴露敏感数据// ❌ 错误暴露数据库信息thrownewException(数据库连接失败jdbc:mysql://192.168.1.100:3306/db);// ✅ 正确友好提示thrownewException(系统繁忙请稍后重试);八、核心知识点速记卡 必背知识点异常分类编译时异常必须处理外部因素运行时异常可选处理代码逻辑四大关键字try-catch捕获处理throws声明抛出throw手动抛出finally必定执行资源清理常见异常NullPointerException空指针IllegalArgumentException参数非法NumberFormatException数字格式IOExceptionIO操作SQLException数据库操作自定义异常继承RuntimeException包含code和message提供构造方法和getter处理原则捕获具体异常记录日志友好提示finally清理资源禁止空catch禁止finally中return 面试检查清单能说清异常体系结构能区分编译时和运行时异常能手写字符串转整数含异常处理能手写自定义异常类能说清try-catch-finally执行顺序能说清finally中return的坑能列举5个以上常见异常能说清throw和throws的区别能说清Exception和Error的区别知道try-with-resources用法九、实战代码模板模板1统一异常处理器Spring Boot这个在博主之前的博文里面有感兴趣的可以翻看博主以前的文章哦RestControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(ParamValidException.class)publicResulthandleParamValid(ParamValidExceptione){returnResult.error(e.getCode(),e.getMessage());}ExceptionHandler(Exception.class)publicResulthandleException(Exceptione){log.error(系统异常,e);returnResult.error(系统繁忙请稍后重试);}}模板2业务方法异常处理publicvoidbusinessMethod(Stringparam){// 1. 参数校验if(paramnull||param.isEmpty()){thrownewParamValidException(参数不能为空);}// 2. 业务逻辑try{// 数据库操作dao.save(param);}catch(SQLExceptione){log.error(数据库操作失败,e);thrownewBusinessException(操作失败请重试);}}模板3资源管理// 推荐try-with-resourcespublicStringreadFile(Stringpath){try(BufferedReaderreadernewBufferedReader(newFileReader(path))){returnreader.readLine();}catch(IOExceptione){log.error(文件读取失败,e);returnnull;}}十、学习建议2小时学习路径第1小时理论基础0-20分钟异常体系和分类20-40分钟四大关键字用法40-60分钟常见异常速查第2小时实战练习0-30分钟手撕3道真题30-50分钟背诵面试问答50-60分钟复习避坑指南进阶学习源码阅读Throwable类的实现框架应用Spring的异常处理机制性能优化异常对性能的影响日志规范异常日志的最佳实践结语Java异常处理是面试必考基础中小厂重点考察基础概念理解常见异常识别手写代码能力规范和避坑掌握本文内容足以应对90%的异常相关面试题。建议理论部分理解记忆真题代码手写3遍面试前快速复习速记卡祝面试顺利作者[识君啊]