1. 介绍

Java 中的 assert 关键字允许开发者快速验证程序中的某些假设或状态。本文将深入探讨如何使用 Java 的 assert 关键字,以及在实际开发中的注意事项。

2. Java 断言的历史

Java 的 assert 关键字自 Java 1.4 版本引入,已经存在相当长时间。然而,它仍是一个鲜为人知的关键字,能显著减少样板代码并提升代码可读性。

例如,在代码中我们经常需要验证某些可能影响程序正常运行的条件。通常我们会这样写:

Connection conn = getConnection();
if(conn == null) {
    throw new RuntimeException("Connection is null");
}

使用断言后,我们可以用单个 assert 语句替代整个 if-throw 结构:

Connection conn = getConnection();
assert conn != null;

3. 启用 Java 断言

由于 Java 断言使用 assert 关键字,无需导入任何库或包。但需要注意:

⚠️ 向后兼容性问题:在 Java 1.4 之前,"assert" 可以作为变量名、方法名等合法标识符。这可能导致旧代码在新 JVM 上运行时产生命名冲突。

因此,JVM 默认禁用断言验证。必须通过命令行参数显式启用:

  • 使用 -enableassertions 或其简写 -ea
java -ea com.baeldung.assertion.Assertion

上述命令为所有类启用断言。也可针对特定包或类启用:

java -ea:com.baeldung.assertion... com.baeldung.assertion.Assertion

同样,可通过 -disableassertions-da 禁用特定包/类的断言。四种参数可组合使用。

4. 使用 Java 断言

添加断言只需使用 assert 关键字并跟随一个布尔条件:

public void setup() {
    Connection conn = getConnection();
    assert conn != null;
}

Java 还提供第二种语法,可附加错误信息字符串:

public void setup() {
    Connection conn = getConnection();
    assert conn != null : "Connection is null";
}

两种方式都在验证外部资源连接是否返回非空值。若值为 null,JVM 会**自动抛出 AssertionError**。

第二种方式会在异常堆栈中显示附加信息,便于调试。启用断言后的运行结果示例:

Exception in thread "main" java.lang.AssertionError: Connection is null
        at com.baeldung.assertion.Assertion.setup(Assertion.java:15)
        at com.baeldung.assertion.Assertion.main(Assertion.java:10)

5. 处理 AssertionError

AssertionError 继承自 Error,而 Error 继承自 Throwable。这意味着 AssertionError非受检异常

因此:

  • 使用断言的方法无需声明抛出该异常
  • 调用代码不应尝试捕获它

重要原则AssertionError 用于表示程序中不可恢复的条件,永远不要尝试处理或恢复这类错误。

6. 最佳实践

使用断言时最关键的是:断言可能被禁用,切勿假设它们一定会执行。因此需牢记以下要点:

必须检查的场景

  • 始终检查空值和空的 Optional(在适当位置)
  • 避免在公共方法输入验证中使用断言,改用 IllegalArgumentExceptionNullPointerException
  • 不要在断言条件中调用方法,应先将方法结果赋给局部变量再断言

适用场景

  • 永远不会执行的代码路径(如 switch 的 default 分支)
  • 永不终止的循环之后
  • 内部不变量验证

避免场景

  • 公共 API 的参数校验
  • 可能产生副作用的条件检查
  • 需要保证执行的关键逻辑

7. 总结

Java 的 assert 关键字虽已存在多年,仍是语言中鲜为人知的特性。它能有效减少样板代码,提升可读性,并在开发早期帮助识别缺陷。

但请牢记:断言默认禁用,切勿在代码中依赖其必然执行。合理使用断言能让代码更简洁,但滥用可能导致生产环境出现意外行为。

完整源代码可在 GitHub 获取。


原始标题:Using Java Assertions