【编程规范】断言(assert)

用错误处理代码处理可能发生的情况 用断言处理理论上绝不应该发生的情况

什么是断言?

断言是一种开发期自检机制,用于验证程序中的内部假设是否成立。

可以把断言理解为:

👉 可执行的注释 👉 开发阶段的安全网 👉 用于捕获逻辑错误,而不是处理业务错误

断言失败说明:

❗ 程序存在 Bug ❗ 某个“不可能发生”的情况发生了

此时应立即终止程序,而不是尝试恢复。

断言 vs 错误处理

场景 应使用
用户输入错误 if / 异常处理
外部数据不可信 if / 异常处理
网络 / IO 失败 异常处理
内部逻辑不变量被破坏 assert

示例:

// ❌ 错误:用 assert 检查用户输入
assert age >= 0;

// ✔ 正确:使用业务校验
if (age < 0) {
    throw new IllegalArgumentException("age must >= 0");
}

断言的语法(以 Java 为例)

assert booleanExpression;

assert booleanExpression : errorMessage;

行为:

  • 表达式为 true → 程序继续执行
  • 表达式为 false → 抛出 AssertionError 并终止

⚠ Java 默认关闭断言,需使用 -ea 启用

断言的典型使用位置

1️⃣ 校验内部参数状态

用于验证函数调用方已保证的前置条件

int resetBufferSize(int newSize) {
    assert newSize >= 0;
    assert newSize <= MAX_BUFFER_SIZE;

    ...
}

注意: 如果 newSize 来自用户输入,则应使用 if + 异常,而不是 assert

2️⃣ 验证不变量(Invariant)

assert balance >= 0 : "Balance should never be negative";

用于确保:

  • 数据结构状态合法
  • 对象生命周期正确
  • 算法中间状态合理

3️⃣ 不可达代码(Unreachable Code)

switch (status) {
    case READY:
    case RUNNING:
    case STOPPED:
        break;
    default:
        assert false : "Unknown status";
}

一次只做一件事

❌ 不推荐:

assert(nOffset >= 0 && nOffset + nSize <= m_nInformationSize);

问题:

  • 失败时无法快速定位是哪一个条件错误

✔ 推荐:

assert nOffset >= 0;
assert nOffset + nSize <= m_nInformationSize;

断言不能有副作用

断言在很多语言中只在调试模式启用,发布版本会被移除。

因此:

❌ 错误写法:

assert i++ < 100;   // 发布版不会执行 i++

✔ 正确写法:

assert i < 100;
i++;

原则:

👉 断言表达式必须是纯判断,不得修改状态

性能说明

断言的开销主要来自:

  • 表达式计算
  • 错误信息构造
  • 失败时的栈跟踪

因此:

  • 高频路径(热点循环)中应谨慎使用
  • 复杂字符串拼接应避免

例如:

// ❌ 即使断言关闭,也会构造字符串
assert x > 0 : "value = " + heavyToString(obj);

可改为:

assert x > 0 : obj;

或仅在调试代码中使用。

与防御式编程的区别

项目 断言 防御式编程
目的 捕获程序员错误 防止系统崩溃
是否面向用户
失败后行为 直接终止 可恢复
是否在生产启用 通常关闭 必须启用

一句话:

👉 断言保护开发者 👉 防御式编程保护系统

最佳实践

✔ 用于验证内部不变量 ✔ 用于标记不可能发生的分支 ✔ 每个断言只检查一个条件 ✔ 断言表达式必须无副作用 ✔ 不用于用户输入校验 ✔ 不依赖断言保证业务逻辑正确

代码风格建议:

assert condition : "明确的错误说明";

并与业务代码保持视觉分隔:

assert size >= 0;

process(size);

反模式(常见误用)

❌ 用断言替代参数校验 ❌ 在断言中写函数调用(有副作用) ❌ 在生产逻辑中依赖断言 ❌ 在热点循环中滥用断言 ❌ 使用复杂布尔表达式

总结

断言的本质:

👉 用于验证“程序员的假设” 👉 发现 Bug 时立即失败 👉 不参与业务逻辑

使用口诀:

对内用断言,对外用异常 断言不改状态,只做判断

#java#
java知识 文章被收录于专栏

java知识详解

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
11136次浏览 95人参与
# 你的实习产出是真实的还是包装的? #
1966次浏览 42人参与
# 巨人网络春招 #
11380次浏览 223人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7655次浏览 43人参与
# 简历第一个项目做什么 #
31758次浏览 341人参与
# 重来一次,我还会选择这个专业吗 #
433574次浏览 3926人参与
# 米连集团26产品管培生项目 #
6044次浏览 216人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187230次浏览 1122人参与
# 牛客AI文生图 #
21453次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152470次浏览 888人参与
# 研究所笔面经互助 #
118976次浏览 577人参与
# 简历中的项目经历要怎么写? #
310388次浏览 4219人参与
# AI时代,哪些岗位最容易被淘汰 #
63881次浏览 828人参与
# 面试紧张时你会有什么表现? #
30518次浏览 188人参与
# 你今年的平均薪资是多少? #
213155次浏览 1039人参与
# 你怎么看待AI面试 #
180177次浏览 1258人参与
# 高学历就一定能找到好工作吗? #
64339次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76552次浏览 374人参与
# 我的求职精神状态 #
448151次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363545次浏览 2638人参与
# 腾讯音乐求职进展汇总 #
160685次浏览 1112人参与
# 校招笔试 #
471269次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务