通过反射机制,比较两个对象的字段值的差异

开发需求中会存在比较前端传来的数据与后台数据有哪些数据发生了改变,一个一个字段比较太麻烦了,通过以下方法可以便捷的比较出来

java 复制代码
//实现方法
 private static List<ChangeContentDTO> getDifferentField(Object obj, Object afterObj) {
        try {
            //首先,创建一个空的列表用于存储变化的内容。
            List<ChangeContentDTO> changeContentDTOList = new ArrayList<>();
            //检查传入的两个对象是否为空,如果任何一个对象为空,则直接返回空列表。
            if (Objects.isNull(obj) || Objects.isNull(afterObj)) {
                return changeContentDTOList ;
            }
            // 获取对象的 Class 对象,然后获取这个 Class 对象的所有字段。
            Class<?> clazz = obj.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                // 遍历这些字段,对于每一个字段,首先设置它可以被访问(因为默认情况下,Java 的私有字段是不能被直接访问的)。
                field.setAccessible(true);
                if (Objects.isNull(field.get(obj))) {
                    continue;
                }
                DefinedAnnotation annotation= field.getDeclaredAnnotation(DefinedAnnotation.class);
                //检查字段的值是否为空,如果为空,则跳过这个字段。
                if (Objects.nonNull(annotation)&&!Objects.equals(field.get(obj), field.get(afterObj))) {
                    //获取字段的注解,如果字段有定义的注解,并且字段的值在两个对象中不同,则创建一个 DTO 对象,将字段的名称、注解的名称、变化前的值和变化后的值存入 DTO 对象,然后将这个 DTO 对象添加到列表中。
                    ChangeContentDTO dto = ChangeContentDTO.builder()
                            .fieldCode(field.getName())
                            .fieldName(annotation.name())
                            .changeBefore(field.get(obj))
                            .changeAfter(field.get(afterObj)).build();
                    changeContentDTOList.add(dto);
                }
            }
            return changeContentDTOList;
        } catch (IllegalAccessException e) {
            throw new BusinessException(BasicErrorCode.BIZ_ERROR, "通过反射获取对象字段的值失败");
        }

    }
java 复制代码
//创建bean对象存储变化的数据
@ApiModel("变更内容DTO")
@Getter
@Setter
@Builder
public class ChangeContentDTO {

    @ApiModelProperty("字段名称")
    private String fieldCode;

    @ApiModelProperty("字段名称")
    private String fieldName;

    @ApiModelProperty("变更前的内容")
    private Object changeBefore;

    @ApiModelProperty("变更后的内容")
    private Object changeAfter;

}
java 复制代码
//main方法测试
 public static void main(String[] args) {
        ResourceEntity resourceEntity = new ResourceEntity();
        ResourceEntity resourceEntity1 = new ResourceEntity();
        resourceEntity.setCode("111");
        resourceEntity1.setCode("222");
        resourceEntity.setName("name");
        resourceEntity1.seName("name");
        List<ChangeContentDTO> list = getDifferentField(resourceEntity, resourceEntity1);
        System.out.println(list);
    }
相关推荐
code2cat1 小时前
Java工具篇之Maven:从pom.xml到测试通过的JAR
xml·java·maven
wuminyu8 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
txxzjmzlh8 小时前
SpringBoot 配置⽂件
java·spring boot·spring
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
骑着蜗牛撵大象3279 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕9 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南10 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
香蕉大香蕉(06敬畏市场)10 小时前
MySQL 单点详解(07)
java·数据库·mysql·ai·博客·八股
nice_lcj52011 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
骑着蜗牛撵大象32711 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp