在 Java 中使用 Assert(断言) 时,核心原则是:断言只用于“程序内部逻辑正确性”的检查,而不是用来处理“可预期的运行时错误”。下面从适用场景、最佳实践、常见误区、与异常的区别、示例几个方面系统说明。
assert condition;
assert condition : "错误信息";
java -ea MyApp
# 或
java -enableassertions MyApp
断言用于表达:
“如果这个条件不成立,说明程序有 bug。”
✅ 正确示例:
int divide(int a, int b) {
assert b != 0 : "除数不能为 0";
return a / b;
}
❌ 错误示例:
// 外部输入不可信,不能用断言
assert userInput >= 0;
对外方法参数校验应使用异常,而不是断言
✅ 正确:
public void setAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("age 不能为负数");
}
}
❌ 错误:
public void setAge(int age) {
assert age >= 0;
}
原因:
❌ 错误示例:
assert list.remove(x);
✅ 正确:
boolean removed = list.remove(x);
assert removed : "x 应该存在于 list 中";
断言表达式可能在生产环境不执行
非常适合用于:
示例:
private void process() {
assert state == State.READY : "状态异常";
// ...
}
断言是:
生产环境通常 不启用断言
assert index >= 0 && index < size :
"index=" + index + ", size=" + size;
有助于快速定位问题。
try {
assert false;
} catch (AssertionError e) {
// ❌ 错误做法
}
AssertionError 表示严重错误,不应被捕获或恢复。
| 场景 | 使用断言 | 使用异常 |
|---|---|---|
| 程序内部逻辑错误 | ✅ | ❌ |
| 参数校验(public 方法) | ❌ | ✅ |
| 用户输入错误 | ❌ | ✅ |
| 文件 / 网络失败 | ❌ | ✅ |
| 永远不该发生的情况 | ✅ | ❌ |
✅ 适合用断言:
default:
assert false : "不可能到达的分支";
❌ 不适合用断言:
// 前置条件
assert param != null : "param 不应为 null";
// 状态检查
assert this.state == EXPECTED : "状态异常";
// 不可能情况
assert false : "非法状态";
断言是给程序员看的,不是给用户看的;
异常处理的是“可能发生的错误”,断言处理的是“不该发生的错误”。
如果你愿意,我也可以:
assert vs JUnit assertThat免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。