Java参数 之 严格求值
问题描述:.ge(StringUtils.isNotBlank(param.getCreateTimeStart()),CommonFileInfo::getCreatetime, dtf.parse(param.getCreateTimeStart())) 报空指针异常。
关键在于 Java 中方法参数的求值顺序。
问题分析
你写的代码类似于 MyBatis-Plus 的条件构造器(如 QueryWrapper)中的链式调用:
.ge(
StringUtils.isNotBlank(param.getCreateTimeStart()),
CommonFileInfo::getCreatetime,
dtf.parse(param.getCreateTimeStart())
)
你期望的是:
- 如果
param.getCreateTimeStart()是null或空字符串,StringUtils.isNotBlank(...)返回false; - 那么
.ge(false, ..., ...)就不会添加该条件,同时dtf.parse(...)不会被执行。
但实际情况是:在调用 .ge(...) 方法之前,Java 会先计算所有传入参数的值,包括第三个参数 dtf.parse(param.getCreateTimeStart())。
所以即使第一个参数是 false,dtf.parse(param.getCreateTimeStart()) 依然会被执行。而 param.getCreateTimeStart() 是 null,导致 dtf.parse(null) 抛出 NullPointerException(或 DateTimeParseException,取决于 dtf 类型)。
✅ 关键点:Java 是严格求值(eager evaluation)语言,方法的所有实参在方法调用前就已求值完成。
正确做法
你需要避免在参数中直接调用可能抛异常的方法,而是将解析逻辑放在条件判断内部。例如:
✅ 方案 1:提前判断并解析
String createTimeStart = param.getCreateTimeStart();
if (StringUtils.isNotBlank(createTimeStart)) {
try {
Date parsedDate = dtf.parse(createTimeStart);
queryWrapper.ge(CommonFileInfo::getCreatetime, parsedDate);
} catch (Exception e) {
// 处理解析异常,如日志记录或抛出业务异常
throw new IllegalArgumentException("创建时间格式错误", e);
}
}
✅ 方案 2:使用三元运算符 + 安全解析(不推荐用于复杂逻辑)
如果 dtf.parse 可以安全处理 null(但通常不行),或者你封装一个安全方法:
Date safeParse(String str) {
if (StringUtils.isBlank(str)) return null;
try {
return dtf.parse(str);
} catch (Exception e) {
return null; // 或抛异常
}
}
// 使用时:
String start = param.getCreateTimeStart();
queryWrapper.ge(
StringUtils.isNotBlank(start),
CommonFileInfo::getCreatetime,
safeParse(start)
);
但注意:即使这样,safeParse(start) 仍然会在 .ge() 调用前执行,只是它内部做了 null 判断。这可以避免异常,但逻辑上仍不如方案 1 清晰。
补充说明:MyBatis-Plus 的 .ge(condition, ...) 设计意图
MyBatis-Plus 的条件方法(如 .eq, .ge)确实支持 condition 参数来控制是否添加条件,但前提是其他参数必须是“可安全求值”的。它并不是“惰性求值”(lazy evaluation),不会因为 condition=false 就跳过其他参数的计算。
因此,不能把可能抛异常的表达式直接写在参数里。
总结
- ❌ 错误认知:认为
condition=false时,后面的参数不会被计算。 - ✅ 正确认知:所有参数在方法调用前都会被计算,无论
condition值如何。 - 🔧 解决方案:先判断字符串非空,再解析,最后调用
.ge()。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19491988

浙公网安备 33010602011771号