本文介绍一种基于泛型与函数式编程的简洁方案,通过自定义 setFieldIfNotEmpty 方法统一处理 27 个字段的非空校验与 Setter 赋值,避免重复 if 判断,提升代码可读性与可维护性。
本文介绍一种基于泛型与函数式编程的简洁方案,通过自定义 `setfieldifnotempty` 方法统一处理 27 个字段的非空校验与 setter 赋值,避免重复 if 判断,提升代码可读性与可维护性。
在构建 DTO(Data Transfer Object)与 Builder 模式协同使用的场景中,常需对大量 String 类型字段进行 null 和空字符串("")校验后再赋值。若为每个字段单独编写 if (!ObjectUtils.isEmpty(...)) 判断(如原始代码所示),不仅冗余度高、易出错,更严重损害可维护性——尤其当字段数量达 27 个时。
推荐采用泛型 + Consumer 的函数式封装方式,将校验逻辑与赋值行为解耦:
import org.springframework.util.ObjectUtils;
import java.util.function.Consumer;
private <T> void setFieldIfNotEmpty(Consumer<T> setter, T value) {
if (ObjectUtils.isNotEmpty(value)) {
setter.accept(value);
}
}该方法适用于任意引用类型(包括 String、Integer、LocalDateTime 等),利用 ObjectUtils.isNotEmpty() 安全判断:对 String 自动排除 null 和 "";对集合/数组/Map 排除 null 或空;对其他对象仅判 null。
调用时以方法引用方式传入对应 Setter,语义清晰且类型安全:
setFieldIfNotEmpty(builder::setSettingType, updateRequest.getSettingType()); setFieldIfNotEmpty(builder::setSettingCode, updateRequest.getSettingCode()); setFieldIfNotEmpty(builder::setExecutionEndDate, updateRequest.getExecutionEndDate()); // 注意:boolean 类型不适用此校验(无“空”概念),直接赋值 builder.setStartToday(updateRequest.isStartToday());
✅ 优势总结:
- ✅ 零重复逻辑:校验规则集中一处,修改只需调整 ObjectUtils.isNotEmpty() 或自定义判断逻辑;
- ✅ 强类型安全:编译期检查 Setter 与 value 类型匹配;
- ✅ 可扩展性强:后续可轻松增强为支持默认值回退(如 setFieldIfNotEmptyOrElse(..., defaultValue));
- ✅ 兼容主流工具类:ObjectUtils 来自 Spring Framework,轻量无额外依赖;若未引入 Spring,可用 Apache Commons Lang 的 StringUtils.isNotBlank() 替代字符串专用判断。
⚠️ 注意事项:
- ObjectUtils.isNotEmpty() 对 Boolean、Number 等包装类型仅判 null,不视为“空”,因此 boolean 基本类型或明确需赋值的字段(如 startToday)应绕过此校验直接设置;
- 若 DTO 中存在 List、Map 等集合字段,isNotEmpty() 同样适用,无需额外分支;
- 避免在 setter 中执行耗时操作——Consumer 是延迟执行的,但应确保其内部逻辑轻量。
该模式已在多个中大型项目中验证,可将 27 个字段的赋值代码从百行 if 块精简至十余行,显著降低认知负荷与出错概率。

















