记一次@EqualsAndHashCode的疑惑

记一次@EqualsAndHashCode的疑惑

Lombok的使用真的是让开发人员欲罢不能,一个@Data不管有多少属性全部搞定,以后加字段也不用从新生成get和set方法。不过这里还是有一个小坑需要注意一下,举个例子:
public class EqualsAndHashCodeTest {
    @Data
    public class BasePo implements Serializable {
        public final static String DEFAULT_USERNAME = "system";
        private Long id = 0L;
        private String createdBy = DEFAULT_USERNAME;
        private String updatedBy = DEFAULT_USERNAME;
        private Date createdTime = Date.from(ZonedDateTime.now().toInstant());
        private Date updatedTime = Date.from(ZonedDateTime.now().toInstant());
    }

    @Data
    @NoArgsConstructor
    @Accessors(chain = true)
    public class Resource extends BasePo {
        private String code;
        private String name;
        private String type;
        private String url;
        private String method;
        private String description;
    }

    @Data
    @NoArgsConstructor
    @Accessors(chain = true)
    public class Resource1{
        private String code;
        private String name;
        private String type;
        private String url;
        private String method;
        private String description;
    }

    public void test(){
        // 创建两个相同对象
        Resource resource1 = new Resource();
        Resource resource2 = new Resource();

        // 两个对象父类属性设置不同的值
        resource1.setId(1L);
        resource1.setCreatedBy("123456");
        resource1.setName("123456");

        resource2.setId(2L);
        resource2.setCreatedBy("654321");
        resource2.setName("123456");

        // 看下两个对象的打印,明明是两个不同对象,但是他们的hashCode确相同,equals方法更是判定两个对象一样
        System.out.println(JSONObject.toJSONString(resource1));
        System.out.println(JSONObject.toJSONString(resource2));
        System.out.println("resource1 hashCode : " + resource1.hashCode());
        System.out.println("resource2 hashCode : " + resource2.hashCode());
        System.out.println(resource1.equals(resource2));

        // 正确使用,在Resource对象上面添加@EqualsAndHashCode(callSuper = true),保证从写hashCode和equals方法时加入父类属性
    }


    public static void main(String[] args) {
        new EqualsAndHashCodeTest().test();
    }
}

看下打印:

{"createdBy":"123456","createdTime":1564137042686,"id":1,"name":"123456","updatedBy":"system","updatedTime":1564137042687}
{"createdBy":"654321","createdTime":1564137042687,"id":2,"name":"123456","updatedBy":"system","updatedTime":1564137042687}
resource1 hashCode : 1342316317
resource2 hashCode : 1342316317
true

我们明明创建了两个不同对象,但是的出来的hashCode确相同,是不是很悲催。
@Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。其中@EqualsAndHashCode这个属性重写hashCode和equals方法,它默认是不添加父类属性的重写,所以如果继承父类时候使用@Data需要加上@EqualsAndHashCode(callSuper = true)添加上父类属性重写hashCode和equals。

{"createdBy":"123456","createdTime":1564137336096,"id":1,"name":"123456","updatedBy":"system","updatedTime":1564137336097}
{"createdBy":"654321","createdTime":1564137336097,"id":2,"name":"123456","updatedBy":"system","updatedTime":1564137336097}
resource1 hashCode : -496642359
resource2 hashCode : -839607981
false

这才是我们想要的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值