如何更优雅地实现Java对象多个必填字段的非空校验
注意:你当前提供的Person类中
age、postcode为int基本类型,默认值为0不会为null,如果需要校验空值需先改为包装类型Integer。
方案1:使用Java Bean Validation(JSR-380)标准校验框架
这是Java生态通用的字段校验标准,企业开发最常用,完全不用手写if判断,注解配置即可实现复杂校验逻辑。
- 第一步引入依赖:Spring Boot项目直接引入
spring-boot-starter-validation,普通Java项目引入hibernate-validator即可。 - 第二步给POJO字段加校验注解
public class Person { @NotNull(message = "name不能为空") private String name; @NotNull(message = "age不能为空") private Integer age; private String address; @NotNull(message = "postcode不能为空") private Integer postcode; // 省略getter、setter }
- 第三步调用校验接口
import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import java.util.Set; // 全局初始化一次即可 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Person person = new Person(); person.setName("Cookie"); person.setAge(20); // 执行校验,返回的集合为空则说明校验通过 Set<?> violations = validator.validate(person); if (violations.isEmpty()) { return true; } // 可批量获取所有校验失败的提示信息 violations.forEach(v -> System.out.println(v.getMessage()));
优势:支持自定义校验规则、分组校验、嵌套对象校验等复杂场景,20+个必填字段只需要每个加一个注解即可,维护成本极低。
方案2:反射实现通用校验工具(无额外依赖)
如果不想引入第三方框架,可以用反射封装通用校验方法,不用逐个字段写if:
import java.lang.reflect.Field; import java.util.List; public class ValidationUtils { /** * 校验对象指定字段是否不为null * @param obj 待校验对象 * @param requiredFields 必填字段名列表 * @return 校验通过返回true,否则返回false */ public static boolean validateRequiredFields(Object obj, List<String> requiredFields) throws Exception { for (String fieldName : requiredFields) { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); Object value = field.get(obj); if (value == null) { System.out.println("必填字段" + fieldName + "为空"); return false; } // 可扩展规则:字符串判断非空、数字判断大于0等 } return true; } }
使用方式:
Person person = new Person(); person.setName("Cookie"); person.setAge(20); // 直接传入必填字段名列表即可,20+个字段只需要往列表里加字段名 boolean checkPass = ValidationUtils.validateRequiredFields(person, List.of("name", "age", "postcode"));
方案3:Java 8 Function断言链(类型安全)
如果怕反射写错字段名、运行期才报错,可以用方法引用实现编译期可检查的校验链:
import java.util.function.Function; import java.util.function.Predicate; public class PersonValidator { // 通用非空校验规则 private static <T> Predicate<Person> notNull(Function<Person, T> getter) { return p -> getter.apply(p) != null; } // 扩展字符串非空校验规则 private static Predicate<Person> notBlank(Function<Person, String> getter) { return p -> getter.apply(p) != null && !getter.apply(p).trim().isEmpty(); } // 聚合所有必填字段的校验规则,新增字段仅需要加一行and规则 private static final Predicate<Person> PERSON_REQUIRED_CHECK = notBlank(Person::getName) .and(notNull(Person::getAge)) .and(notNull(Person::getPostcode)); public static boolean validate(Person person) { return PERSON_REQUIRED_CHECK.test(person); } }
使用方式:
Person person = new Person(); person.setName("Cookie"); person.setAge(20); boolean pass = PersonValidator.validate(person);
内容的提问来源于stack exchange,提问作者CookieMonster
相关产品推荐
相关产品推荐

