objects.requirenonnull用于方法入口空值校验,提前抛出带提示的nullpointerexception;配合preconditions.checkargument等工具做范围与格式校验,校验须前置、信息明确、不侵入主流程。

在 Java 方法中编写健壮的边界条件校验逻辑,核心是早发现、早报错、信息明确,同时避免侵入业务主流程。推荐用防御式编程思路,结合 JDK 自带工具和语义清晰的检查方式。
使用 Objects.requireNonNull 检查空值
对不可为 null 的参数(如 service、callback、配置对象),优先用 Objects.requireNonNull,它抛出的 NullPointerException 带有自定义提示,比手动 if + throw 更简洁且符合 JDK 惯例。
- 不要写
if (obj == null) throw new NullPointerException("obj must not be null") - 改用
Objects.requireNonNull(obj, "obj must not be null") - 对集合或数组的元素非空需求,可配合 Stream 或显式遍历校验(如
list.stream().noneMatch(Objects::isNull))
用 Guava 或 Apache Commons 简化范围与格式校验
基础数值范围(如 id > 0、length ∈ [1, 256])、字符串非空白、邮箱格式等,不建议手写 if 判断。引入 com.google.common.base.Preconditions 或 org.apache.commons.lang3.Validate 可让校验逻辑更紧凑、语义更强。
Preconditions.checkArgument(id > 0, "id must be positive, got %s", id)Validate.notBlank(name, "name cannot be blank or whitespace")- 这些方法在失败时自动抛出
IllegalArgumentException,消息含实际值,便于排查
把校验逻辑提前到方法入口,拒绝“先执行再兜底”
边界校验必须放在方法第一层执行,不能嵌套在 if 分支里,也不能等到数据库操作后才检查。否则可能引发副作用(如已发消息、已扣款、已写日志)。
- 错误示例:先查数据库,再判断结果是否为空,最后 throw —— 这属于业务逻辑异常,不是边界校验
- 正确做法:参数一进来就验证长度、范围、格式、非空;验证通过才进入主干流程
- 对 DTO 入参,可在 Controller 层用
@Valid注解 + BindingResult,但 Service 层仍需独立校验(避免绕过 Controller 直接调用)
自定义校验时,封装可复用的工具方法并统一异常类型
当项目中有高频校验模式(如“手机号必须是 11 位数字”、“金额最多两位小数”),应抽成静态工具方法,并统一抛出项目级业务异常(如 IllegalArgumentException 子类或自定义 InvalidParamException),避免混用多种异常类型。
- 例如:
Asserts.requireMobileFormat(phone, "phone")内部做正则+长度+非空三合一检查 - 异常信息模板保持一致:“%s must be %s, got '%s'”,方便日志提取和前端提示
- 避免在工具方法里吞异常或返回 boolean —— 校验失败就该中断流程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











