如何简洁验证类中指定10个成员非空?求替代冗长if的方案
几种简洁的特定字段非空验证方案
哈哈,这个场景太熟悉了!一开始用反射全量校验确实爽,但一旦要限定特定字段,那种冗长的if ((id == null) || (type == null) ...)确实让人头大。给你几个实用又简洁的解决方案,按需选就行:
方案1:字段名列表+反射(灵活易维护)
把需要校验的10个字段名存在一个常量列表里,然后通过反射遍历这个列表做非空检查。这样后续要调整校验字段,只需要修改列表,不用改校验逻辑:
import java.lang.reflect.Field; import java.util.Arrays; import java.util.List; public class YourClass { // 这里放需要校验的10个字段名 private static final List<String> REQUIRED_FIELDS = Arrays.asList("id", "type", "name", "code", ...); private Long id; private String type; private String name; // 其他成员变量... public boolean validateRequiredFields() { for (String fieldName : REQUIRED_FIELDS) { try { Field field = this.getClass().getDeclaredField(fieldName); field.setAccessible(true); // 允许访问私有字段 if (field.get(this) == null) { return false; } } catch (NoSuchFieldException | IllegalAccessException e) { // 可以根据业务需求处理异常:比如抛自定义校验异常,或者直接返回false return false; } } return true; } }
优点:只需要维护字段名列表,代码简洁;缺点:反射存在极小的性能开销(但10个字段完全可以忽略),且没有编译期类型检查(字段名写错会在运行时抛出异常)。
方案2:Stream API+方法引用/字段直接引用(类型安全)
如果不想用反射,用Stream把要校验的字段或其getter方法收集起来,用allMatch做统一校验,既简洁又有编译期类型检查:
方式A:用getter方法引用(更符合封装原则)
import java.util.stream.Stream; import java.util.Objects; public class YourClass { private Long id; private String type; private String name; // 其他成员变量... // 对应的getter方法 public Long getId() { return id; } public String getType() { return type; } public String getName() { return name; } // 其他getter... public boolean validateRequiredFields() { return Stream.of( this::getId, this::getType, this::getName, // 剩下7个字段的getter方法引用 ).allMatch(getter -> Objects.nonNull(getter.get())); } }
方式B:直接引用字段(如果字段访问权限允许)
public boolean validateRequiredFields() { return Stream.of( this.id, this.type, this.name, // 剩下7个字段 ).allMatch(Objects::nonNull); }
优点:编译期就能发现字段名错误,类型安全,性能也更好;缺点:调整校验字段时需要修改Stream里的内容,不过10个字段的话也不算麻烦。
方案3:Bean Validation框架(适合大型项目)
如果你的项目已经引入了Bean Validation规范的实现(比如Hibernate Validator),直接给需要校验的字段加@NotNull注解,框架会帮你完成校验,完全不用自己写判断逻辑:
第一步:给字段加注解
import javax.validation.constraints.NotNull; // 或者 Jakarta EE 里的 jakarta.validation.constraints.NotNull; public class YourClass { @NotNull private Long id; @NotNull private String type; // 不需要校验的字段不加注解 private String description; // 其他成员变量... // getter setter... }
第二步:编写校验方法
import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import java.util.Set; import javax.validation.ConstraintViolation; public class YourClass { // 初始化Validator(全局只需要初始化一次) private static final ValidatorFactory VALIDATOR_FACTORY = Validation.buildDefaultValidatorFactory(); private static final Validator VALIDATOR = VALIDATOR_FACTORY.getValidator(); // 其他代码... public boolean validateRequiredFields() { Set<ConstraintViolation<YourClass>> violations = VALIDATOR.validate(this); return violations.isEmpty(); } }
优点:扩展性极强,除了非空还能加其他校验规则(比如@NotEmpty、@Size等),代码完全解耦;缺点:需要引入框架依赖(如果项目还没用到的话)。
内容的提问来源于stack exchange,提问作者coconut
相关产品推荐
相关产品推荐

