Lombok的@Data、@Accessors、@EqualsAndHashCode使用细节

Java编辑器现在有一个Lombok的插件,使用非常方便,IDEA、Eclipse都有对应的插件。

Lombok能通过注解的方式,在编译时自动为类属性生成 构造方法getter()setter()equals()hashcode()toString()方法
这样你写代码就只用关注类属性,对应的以上方法会在编译时自动生成。这样节省了代码量,也使代码看起来更简洁些,即使哪天更改属性名、添加删除属性名 这些方法也会自动更新。


实际项目中看到如下使用片段:

/**
 * xx信息
 *
 * @Author wanglingqiang
 * @Date 2020/6/30 上午10:01
 **/
@Data
@ApiModel(value = "Team(xx信息)")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class Team implements Serializable {
    private static final long serialVersionUID = 7618841591717042342L;

   // ...其他类属性

类上Lombok相关的注解有:

@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)

Entity、DTO、VO类建好后,如上的注解大家都是直接拷贝(至于这些注解都是干嘛的,不知道!别人这么用,我也这么用呗)。但心里还是不放心,于是自己写Demo测试了一下。

@Data:是Lombok的基础注解,这个不用说了。

接下来说说另外两个注解:

@Accessors注解

@Accessors(chain = true)

@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Accessors {
    boolean fluent() default false;

    boolean chain() default false;

    String[] prefix() default {};
}

chain默认值是false,与true有什么区别呢?
在这里插入图片描述
值为true时,setXxx()方法返回的是对象,方便链式调用。比如:team.setTeamNo(“T001”).setTeamName(“Team1”)。

在这里插入图片描述
值为false时,setXxx()方法返回的是void。


@Accessors(fluent = true)

fluent 默认值是false,与true有什么区别呢?
在这里插入图片描述
getXxx()方法变成了xxx()。

在这里插入图片描述
setXxx(String xx)方法变成了xxx(String xx)。

@Accessors(fluent = true) 总结,get/set方法去掉了get、set的前缀,直接使用属性名作为方法名。


@Accessors(prefix = “xxx”)

从语义上理解是前缀的意思,我们来试试它怎么实现前缀的。

在这里插入图片描述
没加prefix属性前,可以看到是常规的getXxx()、setXxx()。

在teamNo属性上加前缀“team”,

    @Accessors(prefix = "team")
    private String teamNo;

再看看teamNo属性的getXxx()、setXxx() ,如下:
在这里插入图片描述
在这里插入图片描述
发现了没,teamNo生成的getXxx()、setXxx()去掉了prefix = "team"的“team”前缀。


总结:
1.如果@Accessors(prefix = “xxx”)作用在类上,会对类的所有属性起作用。
2.如果@Accessors(prefix = “xxx”)作用在属性上,只会对当前属性起作用。
3.prefix 的值"xxx"全部小写,比如getTeamNo(),想要的效果是getNo(),那么prefix="team"才行。“Team”、“teaM”都会匹配不上。


@EqualsAndHashCode

接下来,再看看我们代码里的 @EqualsAndHashCode(callSuper = false)是什么用意。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
    String[] exclude() default {};

    String[] of() default {};

    boolean callSuper() default false;

    boolean doNotUseGetters() default false;

callSuper默认值就是false,所以说我们代码里面写这一行是多余的。

通过示例理解该注解:

/**
 * 分页公共类(父类)
 *
 * @author wanglingqiang
 * @date 2020/7/16 下午6:25
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Page {
    private Integer current = 1; //当前页
    private Integer size = 10; //每页数量
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User extends Page {

    private Integer id;
    private String name;

    public User(Integer current, Integer size, Integer id, String name) {
        super(current, size);
        this.id = id;
        this.name = name;
    }
}

User继承Page,因为callSuper默认值是false,即User的@EqualsAndHashCode(callSuper = false)。

测试类:

public class Test {
    public static void main(String[] args) {
        User user1 = new User(1, 10, 1, "张三");
        User user2 = new User(2, 10, 1, "张三");
        boolean flag = user1.equals(user2);
        System.out.println("flag = " + flag);
    }
}

@EqualsAndHashCode(callSuper = false)时,运行结果:

flag = true

奇怪不,明明属性值不一样,但equal()比较时竟然相等。

@EqualsAndHashCode(callSuper = true)时,运行结果:

flag = false

可以看出,callSuper = true时,子类在重写hashcode()和equals()方法时才会调用父类的属性,即把父类属性包含在一起重写hashcode()和equals()方法。

callSuper有它的实用场景,为true、为false可以根据实际需要设值。


@NoArgsConstructor、@AllArgsConstructor

上面的示例中还有两个Lombok注释:

@NoArgsConstructor
@AllArgsConstructor

这两个注解比较加单,从语义上就能理解,是生成构造方法用的。写上这两个注解的效果,如图:
在这里插入图片描述


  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值