
本文介绍一种基于 java 函数式编程的简洁、可复用方式,通过泛型 + consumer 实现对 dto 字段的 null 和 empty 统一校验,显著减少重复代码,提升 setter 赋值逻辑的可读性与可维护性。
本文介绍一种基于 java 函数式编程的简洁、可复用方式,通过泛型 + consumer 实现对 dto 字段的 null 和 empty 统一校验,显著减少重复代码,提升 setter 赋值逻辑的可读性与可维护性。
在构建 DTO 到实体或 Builder 的映射逻辑时(如使用 Builder 模式批量赋值),常需对 20+ 字段逐一做 null 和空字符串("")、空集合等判空处理。若采用传统 if (!ObjectUtils.isEmpty(...)) 嵌套写法,不仅冗余,还易遗漏、难维护。
推荐采用泛型 + Consumer
private <t> void setFieldIfNotEmpty(Consumer<t> setter, T value) {
if (ObjectUtils.isNotEmpty(value)) {
setter.accept(value);
}
}</t></t>
该方法利用 Spring 的 ObjectUtils.isNotEmpty()(支持 String、Collection、Map、数组及任意对象的 null 安全判断),结合函数式接口 Consumer,将“判空 + 赋值”原子化。调用时只需传入方法引用与待赋值字段:
setFieldIfNotEmpty(builder::setSettingType, updateRequest.getSettingType()); setFieldIfNotEmpty(builder::setSettingCode, updateRequest.getSettingCode()); setFieldIfNotEmpty(builder::setExecutionEndDate, updateRequest.getExecutionEndDate()); // 注意:boolean 类型不适用 isEmpty 判定(primitive 不为 null,且语义上无需判空) builder.setStartToday(updateRequest.getStartToday()); // 直接赋值即可
✅ 优势说明:
- 零重复逻辑:避免 27 次 if (!ObjectUtils.isEmpty(...)) 模板代码;
- 类型安全:泛型约束确保 setter 与 value 类型匹配,编译期校验;
- 可扩展性强:如需增加日志、默认值 fallback 或自定义空值策略,仅需修改 setFieldIfNotEmpty 即可全局生效;
- 兼容主流工具类:ObjectUtils(Spring)、StringUtils(Apache Commons)或自定义判空工具均可无缝替换内部条件。
⚠️ 注意事项:
- ObjectUtils.isNotEmpty() 对 Boolean、Integer 等包装类型有效,但对 boolean/int 等基本类型不适用(它们无法为 null);布尔字段、数值字段应按业务语义决定是否校验(如 startToday 是 boolean,通常直接赋值);
- 若项目未引入 Spring Core,可用 org.apache.commons.lang3.StringUtils.isNotBlank() 替代字符串判空,其他类型需自行组合判断;
- 避免在 setter 内部做空值处理(如 setSettingType(String s) { this.settingType = StringUtils.defaultString(s); }),会污染 DTO 职责——DTO 应保持数据纯洁性,校验与转换应在组装层(如 Service 或 Mapper)完成。
综上,该方案以极简封装实现高复用性,在保障健壮性的同时大幅提升代码整洁度,是处理多字段空值校验的推荐实践。











