java异常体系以throwable为根,error表示jvm级不可恢复错误(如outofmemoryerror),不应捕获;exception分为受检异常(如ioexception,编译强制处理)和非受检异常(如nullpointerexception,属代码缺陷,应通过规范预防)。

Java 异常处理是面试高频考点,核心不在背概念,而在理解设计意图、分清边界、写出合理代码。真正能拉开差距的,是能否讲清“为什么这么设计”“什么场景该用什么方式”“哪些写法看似正确实则危险”。
搞懂异常分类才能不踩坑
Java 异常根类是 Throwable,它只生两个孩子:Error 和 Exception。
-
Error(比如OutOfMemoryError、StackOverflowError)是 JVM 自己扛不住的系统级崩溃,程序不该捕获,更不该重试或“兜底”。面试时若说“用 try-catch 包住 Error 来防止程序退出”,基本就判出局。 -
Exception才是你要管的。它又分两类:
✓ 受检异常(Checked):编译器强制你处理,比如IOException、SQLException。它们代表外部不确定性(文件可能被删、网络可能断),程序逻辑本身没问题,但环境不可控。
✓ 非受检异常(Unchecked):即RuntimeException及其子类,比如NullPointerException、ArrayIndexOutOfBoundsException。它们反映的是代码缺陷——本该提前校验却没做。编译器不拦你,但你应该改代码,而不是靠 catch 挽救。
面试最爱考的 try-catch-finally 细节
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
finally一定执行,哪怕try或catch里写了return。但注意:如果finally里也return,它会覆盖前面的返回值(极不推荐)。 - 多个
catch要按子类在前、父类在后排列。写成catch(Exception e)在前,后面再跟catch(NullPointerException e),编译直接报错——后者永远进不去。 - JDK 7+ 支持一个
catch捕多个异常:catch(IOException | SQLException e),简洁且避免重复逻辑。
自定义异常不是炫技,而是传递语义
别一上来就 class MyException extends Exception。先想清楚:
- 是业务错误(如“余额不足”“用户已注销”)?那就继承
Exception,让调用方必须决策怎么处理; - 还是参数明显非法(如传了负数ID)?继承
RuntimeException更合适,属于调用方的责任,不该强迫上层写一堆 try-catch。 - 构造函数务必传入有意义的 message,比如
new InsufficientBalanceException("账户ID: " + accountId + " 余额不足,当前: " + balance),而不是"操作失败"。
三个高危操作,面试官一听就皱眉
- 空
catch块:catch(Exception e) { }—— 错误被吞掉,问题静默恶化。至少要log.error("xxx failed", e)。 -
catch(Throwable t):连Error都抓,可能把OutOfMemoryError压下去,导致 JVM 带病运行更久、问题更难定位。 - 在
finally里写可能抛异常的代码(比如未判空就resource.close()),会掩盖原异常。用try-with-resources替代手动 close,既安全又简洁。
本质上,异常处理考的是工程判断力:什么该拦、什么该放、什么该改、什么该报。代码写得“能跑”不难,写得“可维护、可诊断、可演进”才是真功夫。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










