Java 断言实战指南:尽早发现 Bug 与保障代码可靠性
Java 断言
学习 Java assert 语句如何帮助尽早捕获 Bug、验证假设并提升代码质量。
断言是轻量级、仅开发者使用的机制,用于测试执行期间应始终为真的条件。它们显式启用且从生产构建中省略,因此从不影响运行时性能。
语法
assert condition;
此处 condition 为预期评估为 true 的布尔表达式。若条件为 false 且启用断言,JVM 抛出 AssertionError 并停止程序。
启用断言
断言默认禁用。用 JVM 开关启用:
java -ea:arguments java -enableassertions:arguments
启用后,true 条件正常继续;false 条件触发 AssertionError 并停止执行。
示例 1:基础断言
class Main { public static void main(String args[]) { String[] weekends = {"Friday", "Saturday", "Sunday"}; assert weekends.length == 2; System.out.println("There are " + weekends.length + " weekends in a week"); } }
禁用断言时输出:
There are 3 weekends in a week
启用断言产生:
Exception in thread "main" java.lang.AssertionError
扩展断言语法
包含诊断消息:
assert condition : expression;
expression 传给 AssertionError 构造器,条件失败时显示。
示例 2:带消息的断言
class Main { public static void main(String args[]) { String[] weekends = {"Friday", "Saturday", "Sunday"}; assert weekends.length==2 : "There are only 2 weekends in a week"; System.out.println("There are " + weekends.length + " weekends in a week"); } }
启用时输出:
Exception in thread "main" java.lang.AssertionError: There are only 2 weekends in a week
定向断言激活
为特定类或包激活断言:
- 所有用户类:
java -ea - 特定类:
java -ea:AnimalClass Main - 包及子包:
java -ea:com.animal... Main - 无名包:
java -ea:... Main
系统类用 -esa 或 -enablesystemassertions 启用。禁用用 -da 和 -dsa 类似模式。
断言的价值场景
- 不可达代码: 验证标记为不可达的代码确实不可达。
void unreachableCodeMethod() { System.out.println("Reachable code"); return; // 不可达代码 System.out.println("Unreachable code"); assert false; } - 缺失默认分支: 确保 switch 语句穷尽处理。
switch (dayOfWeek) { case "Sunday": System.out.println("It’s Sunday!"); break; case "Monday": System.out.println("It’s Monday!"); break; // … default: assert false : dayOfWeek + " is an invalid day"; } - 文档化假设: 用断言替代易失效的注释,使其保持同步。
if (i % 2 == 0) { // ... } else { assert i % 2 == 1 : i; // ... }
不应使用断言的场景
- 公共 API 参数检查: 用户提供的输入应触发运行时异常,而非断言错误。
- 有副作用的条件: 避免在断言中调用修改状态的方法,因断言禁用时代码静默运行。
ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" )); ArrayList<String> weekends = new ArrayList<>(Arrays.asList("Sunday", "Saturday" )); boolean removed = weekdays.removeAll(weekends); assert removed;
断言的优势
- 快速、面向开发者的 Bug 检测。
- 生产构建自动移除,确保零运行时成本。
- 减少样板代码,明确意图。
- 重构和优化时增加信心。
java
- 精通 Java 运算符:类型、语法与实战示例
- Java 注释:类型、用法与最佳实践
- 精通 Java if…else:控制流全解析
- 精通 Java 增强 for 循环:语法、示例与最佳实践
- Java break 语句:用法、时机与标签 break 详解
- 精通 Java 数组:声明、初始化与操作全攻略
- 精通 Java 字符串:创建、方法与最佳实践
- 精通 Java 接口:概念、实现与最佳实践
- 精通 Java 匿名内部类:定义、语法与实战示例
- 精通 Java Try-With-Resources:自动资源管理详解
- Java 注解详解:类型、放置位置与实战示例
- 深入理解 Java Vector:用法、特性及与 ArrayList 的对比