以下是 Guava Preconditions 工具类的详细介绍和使用指南,它专注于参数和状态的快速校验,帮助开发者实现 快速失败(Fail-Fast),避免冗长的 if-else
逻辑。
一、Guava Preconditions 简介
- 所属库:Google Guava(核心工具库之一)
- 用途:简化参数校验和状态检查,抛出标准异常(如
IllegalArgumentException
)。 - 核心思想:在方法入口处明确校验条件,增强代码可读性和健壮性。
特点:
- 轻量级,无复杂依赖。
- 支持链式调用和自定义错误消息。
- 适合非 Web 层(如工具类、Service 层)的校验。
二、核心方法及使用示例
1. 参数校验
方法签名 | 用途 | 抛出异常 |
---|---|---|
checkArgument(boolean expression) | 校验方法参数合法性 | IllegalArgumentException |
checkArgument(boolean expression, String errorMsg) | 带自定义错误信息 | IllegalArgumentException |
checkArgument(boolean expression, String template, Object... args) | 格式化错误信息 | IllegalArgumentException |
示例:
public void process(int value, String name) {
Preconditions.checkArgument(value > 0, "值必须为正数,实际值: %s", value);
Preconditions.checkArgument(name != null && !name.isEmpty(), "名称不能为空");
}
2. 非空校验
方法签名 | 用途 | 抛出异常 |
---|---|---|
checkNotNull(T reference) | 校验对象非 null | NullPointerException |
checkNotNull(T reference, String errorMsg) | 带自定义错误信息 | NullPointerException |
示例:
public User createUser(String username, String email) {
Preconditions.checkNotNull(username, "用户名不能为 null");
Preconditions.checkNotNull(email, "邮箱不能为 null");
// 业务逻辑...
}
3. 状态校验
方法签名 | 用途 | 抛出异常 |
---|---|---|
checkState(boolean expression) | 校验对象或系统的状态 | IllegalStateException |
checkState(boolean expression, String errorMsg) | 带自定义错误信息 | IllegalStateException |
示例:
public class ConnectionPool {
private boolean initialized = false;
public void connect() {
Preconditions.checkState(!initialized, "连接池已初始化");
// 初始化逻辑...
initialized = true;
}
}
4. 索引和范围校验
方法签名 | 用途 | 抛出异常 |
---|---|---|
checkElementIndex(int index, int size) | 校验索引在列表/数组的有效范围内([0, size) ) | IndexOutOfBoundsException |
checkPositionIndex(int index, int size) | 校验位置在列表/数组的有效范围内([0, size] ) | IndexOutOfBoundsException |
checkPositionIndexes(int start, int end, int size) | 校验区间 [start, end) 的有效性 | IndexOutOfBoundsException |
示例:
public String getElement(List<String> list, int index) {
Preconditions.checkElementIndex(index, list.size(), "索引越界");
return list.get(index);
}
三、集成 Guava Preconditions
1. 添加依赖
Maven:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>32.1.3-jre</version> <!-- 使用最新版本 --> </dependency>
Gradle:
implementation 'com.google.guava:guava:32.1.3-jre'
2. 静态导入(推荐)
import static com.google.common.base.Preconditions.*;
四、高级用法
1. 链式调用
public void validateInput(String input, int maxLength) {
checkArgument(input != null, "输入不能为 null");
checkArgument(input.length() <= maxLength, "输入长度不能超过 %s 字符", maxLength);
}
2. 自定义错误消息模板
支持 %s
占位符,动态填充参数:
Preconditions.checkArgument(value >= min && value <= max,
"值必须在 %s 和 %s 之间,实际值: %s", min, max, value);
五、对比传统校验方式
1. 传统方式
public void process(int value) {
if (value <= 0) {
throw new IllegalArgumentException("值必须为正数,实际值: " + value);
}
// 业务逻辑...
}
2. 使用 Preconditions
public void process(int value) {
checkArgument(value > 0, "值必须为正数,实际值: %s", value);
// 业务逻辑...
}
优势:
- 代码更简洁,错误信息格式化更便捷。
- 统一异常类型,便于全局异常处理。
六、最佳实践
适用场景:
- 方法参数校验(如公共 API、工具类)。
- 对象状态校验(如初始化状态、资源是否关闭)。
- 替代手动抛异常,减少重复代码。
不适用场景:
- 复杂业务规则校验(需结合业务逻辑)。
- Web 层参数校验(优先使用 Hibernate Validator)。
性能优化:
- 避免在循环内部频繁调用
Preconditions
(可提前校验)。
- 避免在循环内部频繁调用
错误消息规范:
- 明确错误原因和期望值(如
"年龄必须 ≥ 18,实际值: 15"
)。
- 明确错误原因和期望值(如
七、与其他校验框架对比
工具 | 适用场景 | 特点 |
---|---|---|
Guava Preconditions | 方法参数、状态校验 | 轻量级,快速失败,适合代码内部校验 |
Hibernate Validator | DTO 对象校验 | 声明式注解,适合 Web 层参数校验 |
Apache Commons Validate | 简单字段校验 | 提供通用校验工具类 |
八、完整示例
import static com.google.common.base.Preconditions.*;
public class PaymentService {
public void processPayment(String orderId, double amount) {
// 参数校验
checkNotNull(orderId, "订单号不能为 null");
checkArgument(!orderId.isEmpty(), "订单号不能为空");
checkArgument(amount > 0, "金额必须大于 0,实际值: %s", amount);
// 业务逻辑...
}
public void updateStatus(OrderStatus currentStatus, OrderStatus newStatus) {
// 状态校验
checkState(currentStatus.canTransitionTo(newStatus),
"无法从状态 %s 切换到 %s", currentStatus, newStatus);
// 更新逻辑...
}
}
通过 Guava Preconditions,可以显著提升代码的健壮性和可维护性,尤其适合在核心逻辑中快速校验参数和状态。