Lombok 使用教程-@Data | 整合 @ToString, @EqualsAndHashCode, @Getter,@Setter 和 @RequiredArgsConstructor

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

一、简介

@Data是一个方便的快捷注解,它将@ToString@EqualsAndHashCode@Getter/@Setter@RequiredArgsConstructor的功能捆绑在一起。换句话说,@Data生成了所有通常与简单POJOPlain Old Java Objects)和Bean相关的模板:所有字段的getters,所有非final字段的setters,以及适当的toStringequalshashCode实现,这些都涉及到类的字段,还有一个初始化所有final字段的构造函数,以及所有没有初始化器的非final字段,这些都被标记为@NonNull,以确保字段永不为空。

@Data就像在类上有隐式的@Getter@Setter@ToString@EqualsAndHashCode@RequiredArgsConstructor注解一样(除非如果已经存在任何显式编写的构造函数,则不会生成任何构造函数)。但是,这些注解的参数(如callSuperincludeFieldNamesexclude)不能用@Data设置。如果你需要为这些参数中的任何一个设置非默认值,只需明确添加这些注解即可;@Data很聪明,会遵从这些注解。

所有生成的gettersetter的访问级别都是public。要覆盖访问级别,请使用显式@Setter@Getter注释对字段或类进行注释。您还可以使用此注释(通过将其与AccessLevel.NONE结合使用)来禁止同时生成gettersetter

标记为transient的所有字段将不考虑hashCodeequals。所有的静态字段将被完全跳过(不考虑任何生成的方法,也不会为它们生成setter/getter)。

如果类已经包含一个与通常生成的任何方法具有相同名称和参数数量的方法,则不会生成该方法,也不会发出警告或错误。例如,如果您已经有一个签名为equals(AnyType param)的方法,则不会生成equals方法,即使从技术上讲,由于参数类型不同,它可能是一个完全不同的方法。同样的规则也适用于构造函数(任何显式构造函数都会阻止@Data生成构造函数),以及toStringequals和所有gettersetter。您可以使用@lombok.experional.permission标记任何构造函数或方法,以对lombok隐藏它们。

@Data可以很好地处理字段的泛型参数。为了减少为有泛型的类构造对象时的模板,你可以使用staticConstructor参数来生成一个私有构造函数,以及一个返回新实例的静态方法。这样一来,javac就会推断出变量的名字。因此,通过这样的声明。@Data(staticConstructor="of") class Foo<T> { private T x;} 你可以通过Foo.of(5);来创建Foo的新实例。 而不是:new Foo<Integer>(5);

二、示例比较

1. Lombok 写法

    import lombok.AccessLevel;
    import lombok.Setter;
    import lombok.Data;
    import lombok.ToString;
    
    @Data public class DataExample {
      private final String name;
      @Setter(AccessLevel.PACKAGE) private int age;
      private double score;
      private String[] tags;
      
      @ToString(includeFieldNames=true)
      @Data(staticConstructor="of")
      public static class Exercise<T> {
        private final String name;
        private final T value;
      }
    }

2. Java 标准写法

    import java.util.Arrays;
    
    public class DataExample {
      private final String name;
      private int age;
      private double score;
      private String[] tags;
      
      public DataExample(String name) {
        this.name = name;
      }
      
      public String getName() {
        return this.name;
      }
      
      void setAge(int age) {
        this.age = age;
      }
      
      public int getAge() {
        return this.age;
      }
      
      public void setScore(double score) {
        this.score = score;
      }
      
      public double getScore() {
        return this.score;
      }
      
      public String[] getTags() {
        return this.tags;
      }
      
      public void setTags(String[] tags) {
        this.tags = tags;
      }
      
      @Override public String toString() {
        return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";
      }
      
      protected boolean canEqual(Object other) {
        return other instanceof DataExample;
      }
      
      @Override public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof DataExample)) return false;
        DataExample other = (DataExample) o;
        if (!other.canEqual((Object)this)) return false;
        if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
        if (this.getAge() != other.getAge()) return false;
        if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
        if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
        return true;
      }
      
      @Override public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final long temp1 = Double.doubleToLongBits(this.getScore());
        result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
        result = (result*PRIME) + this.getAge();
        result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
        result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
        return result;
      }
      
      public static class Exercise<T> {
        private final String name;
        private final T value;
        
        private Exercise(String name, T value) {
          this.name = name;
          this.value = value;
        }
        
        public static <T> Exercise<T> of(String name, T value) {
          return new Exercise<T>(name, value);
        }
        
        public String getName() {
          return this.name;
        }
        
        public T getValue() {
          return this.value;
        }
        
        @Override public String toString() {
          return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
        }
        
        protected boolean canEqual(Object other) {
          return other instanceof Exercise;
        }
        
        @Override public boolean equals(Object o) {
          if (o == this) return true;
          if (!(o instanceof Exercise)) return false;
          Exercise<?> other = (Exercise<?>) o;
          if (!other.canEqual((Object)this)) return false;
          if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;
          if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;
          return true;
        }
        
        @Override public int hashCode() {
          final int PRIME = 59;
          int result = 1;
          result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
          result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());
          return result;
        }
      }
    }

三、支持的配置项

lombok.data.flagUsage = [warning | error] (默认: not set)
如果配置了@DataLombok会将任何对@Data的使用标记为警告或错误。

lombok.noArgsConstructor.extraPrivate = [true | false] (默认: false)
如果为truelombok将为任何@Data注释类生成一个私有的无参数构造函数,该构造函数将所有字段设置为默认值(null/0/false

四、附属说明

请参阅@ToString@EqualsAndHashCode@Getter/@Setter@RequiredArgsConstructor的附属说明。

关于null性的各种众所周知的注释会导致插入null检查并将其复制到相关位置(例如getter的方法以及构造函数和setter的参数)。有关更多信息,请参阅@Getter/@Setter文档的附属说明。

默认情况下,任何以$符号开头的变量都被自动排除。你可以通过指定一个明确的注释(例如,@Getter@ToString)并使用 "of "参数来包括它们。

参考文献

【1】@Data | All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, @Setter on all non-final fields, and @RequiredArgsConstructor!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值