java 两个Dto对象有字段数据不一致可Object.equals方法却返回了一致?(问题分析与结论)
问题描述
以示意代码非原业务代码描述解释
基础类DownloadCenterBaseParam
子类 DashBoardQueryDto
新建两个对象并比对equals
public static void main(String[] args) {ChannelReportNewVersionQueryDto dto1 = new ChannelReportNewVersionQueryDto();dto1.setCreateTimeBegin("2023-03-01");dto1.setCreateTimeEnd("2023-03-02");dto1.setPageNo(1);dto1.setPageSize(10);ChannelReportNewVersionQueryDto dto2 = new ChannelReportNewVersionQueryDto();dto2.setCreateTimeBegin("2023-03-01");dto2.setCreateTimeEnd("2023-03-02");dto2.setPageNo(3);dto2.setPageSize(10);System.out.println(Objects.equals(dto1, dto2));System.out.println(dto1.hashCode());System.out.println(dto2.hashCode());}
}
运行代码得到的结果,是不是有点懵,明明pageNo这个字段的值一个是1,一个是10,为啥equals还能相等呢?
原因是Lombok @Data注解生成了equals方法,equals方法里并没有对父类的字段进行比对
我们打开生成的字节码文件看看,可以看到并未比对父类的pageNo字段
到此,你弄懂了为啥这两个对象equals会返回相同,解决办法是加注解声明equals方法要比较父类的equals
@EqualsAndHashCode(callSuper = true)
加了注解之后我们再看看编译后的字节码文件
你以为这就完了?再来看看这个
基础类DogBaseDto
子类HuskyDto
测试类
运行结果显示两个对象不相等,怎么办,你懵了吗?我也懵了啊,再去看看字节码
可以从字节码看到,对父类做了equals比对!!!你猜为啥?你可能和我一样会去对比两个类的差别,最开始的类有@FieldNameConstants注解,后面的没有,但是测试过后,这个加或不加都不影响维持现状,另一个就是base类是否在一个目录下,这个测试了仍然不影响。(测试的时候要先删除已经生成的字节码!!!)目前暂未找到原因,要写需求去,我去提个issue试试(https://github.com/projectlombok/lombok/issues/3631),原因找到了,前面那个没有生成super.equals是因为那个类在该项目的api包下,没指定lombok配置,而后面建的类是在core包下,有个lombok.config指定了equals方法一定会调父类的equals。