lombok中@Data及@EqualsAndHashCode

本文讨论了在Java中,即使使用了@Data注解,为了确保equals和hashCode方法正确处理父类属性,为何需要在子类上使用@EqualsAndHashCode(callSuper=true)。同时,分析了equals方法的继承行为和@EqualsAndHashCode注解对父类的影响。
摘要由CSDN通过智能技术生成

问题1

@Data其实已经包含@EqualsAndHashCode了,哪么有些场景 类上使用了@Data,还要使用@EqualsAndHashCode(callSuper = true)?这是出于什么目的呢?

分析

@Data已经包含@EqualAndHashCode,如下所示:

@EqualsAndHashCode的callSuper属性默认为false,即生成的equals函数并不会考虑父类,看下面代码Child1和Child2类的反编译

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class LombokDataTest {
    @Data
    public static class Parent {
        private static String C_P = "P";
        private Long id;
    }

    @Data
    public class Child1 extends Parent {
        private String name;
        public Child1(Long id, String name) {
            setId(id);
            setName(name);
        }
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public class Child2 extends Parent {
        private String name;
        public Child2(Long id, String name) {
            setId(id);
            setName(name);
        }
    }

    @Test
    public void testData() {
        Child1 c11 = new Child1(0L, "n");
        Child1 c12 = new Child1(1L, "n");
        Assertions.assertEquals(c11, c12, "name相等 就应该 equals");

        Child2 c21 = new Child2(0L, "n");
        Child2 c22 = new Child2(1L, "n");
        Assertions.assertNotEquals(c21, c22, "因为加了EqualsAndHashCode,id、name都相等 才equals");
    }
}

 

如上所示,Child2加了@EqualsAndHashCode(callSuper = true),若要equals为true,还需要super.equals为true即行,即父类属性 也相等才行;

上面代码中 测试函数也反应了这个问题;

问题2

@EqualsAndHashCode(callSuper = true)可以进行传递吗?

看下面代码,C1继承Parent并没有加@EqualsAndHashCode(callSuper = true),但C2继承C1并设置了true,哪么C2的equals里会 考虑 Parent类的id属性吗?

根据上面分析,是通过super.equals来实现的,但C1类中equals并没有考虑super.equals, 因此并不会考虑Parent的属性,下面测试函数也证明了

@Data
    public class C1 extends Parent {
        private String name;
    }
    @Data
    @EqualsAndHashCode(callSuper = true)
    public class C2 extends C1 {
        private int age;
        public C2(Long id, String name, int age) {
            setId(id);
            setName(name);
            setAge(age);
        }
    }

    @Test
    public void testEqualsAndHashCode继承传递() {
        C2 c1 = new C2(0L, "n", 10);
        C2 c2 = new C2(1L, "n", 10);
        Assertions.assertEquals(c1, c2);
    }

结论

1.使用@Data时,若涉及equals和hashCode,并且要考虑parent属性,则要加上@EqualsAndHashCode(callSuper = true),否则会导致判断错误(本来不相等,却被判为相等);

2.当前类的@EqualsAndHashCode不会影响其父类的@EqualsAndHashCode;

3.对于注解@EqualsAndHashCode,对 hashCode函数 的处理 类似equals

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值