异常用于处理运行时可预期的外部错误,如文件不存在;断言用于开发阶段验证逻辑假设,如方法返回值非null,默认禁用且生产环境关闭。

异常(Exception)和断言(assert)都是Java中用于检测问题的机制,但它们定位不同、使用场景不同、启用方式也不同。简单说:异常处理的是运行时可能真实发生的错误情况,比如文件不存在、网络超时;而断言检查的是开发阶段本不该出现的逻辑错误,比如某个方法返回值绝不能为null却为null了。
异常:面向生产环境的可控错误处理
异常是Java语言级的错误响应机制,分检查型(checked)和非检查型(unchecked)。它被设计成可捕获、可恢复、可记录,适用于程序运行中外部不可控因素引发的问题。
- 必须显式处理或声明(检查型异常如IOException),否则编译不通过
- 可通过try-catch捕获并做降级、重试、日志等业务应对
- 即使在生产环境开启,也不会影响性能(无额外开销)
- 例如:Integer.parseInt("abc")抛出NumberFormatException,这是典型输入校验失败,应由异常处理
断言:面向开发/测试阶段的逻辑自检工具
assert语句用于验证程序内部假设是否成立,本质是调试辅助手段。默认情况下JVM禁用断言,需加-ea(enable assertions)参数才生效;生产环境通常关闭,避免性能干扰和意外副作用。
- 语法为assert condition : message;,条件为false时抛出AssertionError(继承自Error)
- 不应用于检查用户输入、外部资源状态等“可能出错”的场景——那属于异常范畴
- 适合检查私有方法的前置条件、循环不变式、算法中间状态等“理论上必须为真”的断点
- 例如:assert list != null && !list.isEmpty() : "列表不应为空"; 出现在私有工具方法开头,表示调用方违反契约
关键区别总结
- 目的不同:异常应对可预期的错误场景;断言验证开发者自己的逻辑假设
- 生命周期不同:异常贯穿开发、测试、上线全流程;断言主要活跃于开发和单元测试阶段
- 行为控制不同:异常无法被JVM全局禁用;断言可按包、类甚至开关粒度启用/禁用
- 类型与处理建议不同:异常应被捕获或声明;AssertionError不建议捕获,一旦触发说明代码存在严重缺陷,应修复而非掩盖
什么时候该用哪个?一句话判断
问自己:这个问题是用户操作或环境导致的合理失败?→ 用异常。
还是代码写错了、逻辑走歪了、契约被破坏了?→ 用assert。










