Java8私有方法非空参数校验:@NotNull、断言与抛异常如何选择?
在没有Spring框架加持的环境里,给私有方法做参数非空校验,得选个靠谱的方案才行。咱们挨个拆解你列出的三个选项:
1. @NotNull注解方案
首先明确:@NotNull属于JSR-380(Bean Validation)规范的注解,标准包是javax.validation.constraints.NotNull(Java 9+之后因为Jakarta EE迁移,可能要换成jakarta.validation.constraints.NotNull),常用的实现库是Hibernate Validator。
但这里有个关键问题:Bean Validation默认不会自动校验私有方法。它的设计初衷是校验JavaBean、公共接口方法的参数(比如REST接口的入参),如果要给私有方法用这个注解,你得手动写代码触发校验逻辑,比如:
import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import javax.validation.ConstraintViolation; import java.util.Set; public class MyService { private final Validator validator; public MyService() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } private void myBusinessMethod(@NotNull Object argument) { // 手动触发参数校验 Set<ConstraintViolation<Object>> violations = validator.validate(argument); if (!violations.isEmpty()) { throw new javax.validation.ConstraintViolationException(violations); } // 业务逻辑代码 } }
这种方式对私有方法来说太繁琐了,额外的代码开销不说,还很容易被开发者忽略手动校验的步骤,导致注解形同虚设。所以这个方案不适合私有方法的非空校验。
2. 断言(assert)方案
先看示例代码:
private void myBusinessMethod(Object argument) { assert argument != null : "参数argument不能为null"; // 业务逻辑 }
断言的最大问题是:默认是关闭的。JVM需要通过-ea参数才能开启断言功能,而生产环境几乎不会开启这个参数——这意味着生产环境下你的非空校验会直接被跳过,null参数会直接进入业务逻辑,引发NPE或者其他奇怪的问题。
另外,断言抛出的是AssertionError,属于Error类型,语义上是用来标记程序内部的不可恢复错误,而非业务层面的参数非法问题。所以用断言做私有方法的非空校验非常不安全,绝对不推荐。
3. 抛出IllegalArgumentException方案
示例代码:
private void myBusinessMethod(Object argument) { if (argument == null) { throw new IllegalArgumentException("参数argument不能为空"); } // 业务逻辑 }
这个方案是三个里面最靠谱的,原因如下:
- 无额外依赖:完全基于JDK原生API,任何环境都能直接用;
- 校验逻辑明确:开发者一眼就能看到非空校验的逻辑,不会遗漏;
- 生产环境可靠:不管什么环境,这段if判断都会执行,不会像断言那样被跳过;
- 语义准确:
IllegalArgumentException专门用来表示参数非法的场景,错误信息可以自定义,方便调试排查问题。
总结
在非Spring场景下,私有方法的参数非空校验优先选择抛出IllegalArgumentException的方式,它简单、可靠、无额外成本,能有效避免开发者传入null值引发的问题。
内容的提问来源于stack exchange,提问作者Aguid

