断言不能用于前置条件校验,仅适用于开发阶段内部逻辑检查;异常抛出才是生产环境保障健壮性的标准方式,因断言默认关闭、抛出Error子类且缺乏上下文信息。

Java 中断言(assert)和异常抛出(throw)用途不同,**不能也不应混用做前置条件校验**。断言用于开发阶段的内部逻辑检查,而异常抛出才是生产环境中保障健壮性的标准方式。
断言不是为参数校验设计的
Java 的 assert 语句默认在运行时是关闭的(需显式加 -ea JVM 参数才启用),这意味着:
- 生产环境不开启断言时,所有
assert语句被忽略,前置校验完全失效 - 断言失败抛出的是
AssertionError,属于Error子类,按约定不应被业务代码捕获或处理 - 断言无法提供清晰的错误上下文(如参数名、期望值),不利于调试和 API 使用方理解
用异常抛出做可靠前置校验
推荐使用明确的运行时异常(如 IllegalArgumentException、NullPointerException)配合手动检查:
public void process(String input, int count) {
if (input == null) {
throw new IllegalArgumentException("input must not be null");
}
if (count < 0) {
throw new IllegalArgumentException("count must be non-negative");
}
// 正常逻辑...
}
更简洁的方式是借助 Apache Commons Lang 或 Guava:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
Objects.requireNonNull(input, "input must not be null")-
Preconditions.checkNotNull(input, "input must not be null")(Guava) -
Validate.notNull(input, "input must not be null")(Commons Lang)
断言的合理使用场景
断言适合表达「绝不可能发生」的内部不变量,例如:
- 私有方法执行后某个字段状态必须满足的条件
- 循环结束时归纳变量的终态验证
- 算法分支中理论上不可达路径的兜底标记
示例:
private int findIndex(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) return i;
}
assert false : "target not found in array"; // 开发阶段提示逻辑缺陷
return -1;
}
统一校验建议
若希望兼顾可读性与一致性,可封装校验工具方法:
private static void checkArgument(boolean condition, String message) {
if (!condition) throw new IllegalArgumentException(message);
}
// 使用
checkArgument(input != null, "input is required");
checkArgument(count >= 0, "count cannot be negative");
这样既避免重复模板代码,又确保校验始终生效,且错误类型、消息格式可控。
不复杂但容易忽略:校验逻辑的生命期必须覆盖整个应用生命周期,而断言只服务于开发调试阶段。

















