温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Lombok的功能是什么

发布时间:2021-10-14 10:02:59 来源:亿速云 阅读:123 作者:iii 栏目:编程语言

本篇内容主要讲解“Lombok的功能是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Lombok的功能是什么”吧!

什么是 lombok

Lombok项目是一个Java库,工具库,它会自动在编辑器或构建工具中生成代码,从而使你的Java代码更简洁。不用在给每一个变量生成get和set等方法,还会生成一个功能齐全的Builder,已经自动化日志记录变量,以及更多

常用注解

  • @Setter

  • @Getter

  • @Builder

  • @RequiredArgsConstructor 生成一个该类的构造方法,禁止无参数构造

  • @ToString 重写该类的 toString()方法

  • @EqualsAndHashCode 重写该类的equals() 和 hashCode() 方法

  • @NoArgsConstructor

  • @AllArgsConstructor

  • @Data 等同于 @Setter @Getter @RequiredArgsConstructor @ToString @EqualsAndHashCode 注解之和

  • @Slf4j

写一个简单的类 使用这个类来详细的的看一下 Lombok 帮我们做了什么

package lombok;
public class UserData {
    private String name;
    private int age;
    private boolean good;
}

这个类很简单 代码中没有构造函数、没有get set 方法 使用 javap 工具来看一下

javap 是 jdk 自带的反编译工具、这里先不关心生成的字节码 只看方法

// javap UserData.class
Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
}

JDK当检测到没有默认构造器时,自动生成一个 public 的无参数默认构造器

使用 @Getter

在类 UserData 上增加注解 @Getter

Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
  public java.lang.String getName();
  public int getAge();
  public boolean isGood();
}

反编译后 看到使用驼峰命名方式 增加 get 变量方法 需要注意 boolean 类型 使用的 is 方法

使用 @Setter
Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
  public void setName(java.lang.String);
  public void setAge(int);
  public void setGood(boolean);
}

反编译后 增加 set 变量方法

使用 @RequiredArgsConstructor
Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
}

反编译后 可以看到 和没有注解是一样的 生成一个 无参数构造函数

使用 @ToString
public class lombok.UserData {
  public lombok.UserData();
  public java.lang.String toString();
}

反编译后 可以看到 增加 toString 方法 这里的toString和原生的是有区别的

System.out.println(new UserData().toString());
// 原生toString输出
lombok.UserData@60e53b93 每次生成引用地址会变化
// @ToString输出
UserData(name=null, age=0, good=false)
使用 @EqualsAndHashCode
Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
  public boolean equals(java.lang.Object);
  protected boolean canEqual(java.lang.Object);
  public int hashCode();
}

反编译后 可以看到 增加 equals canEqual hashCode 三个方法

和原生对比下输出

public static void main(String[] args) {
        UserData userData = new UserData();
        System.out.println(userData.equals(new UserData()));
        System.out.println(userData.canEqual(new UserData()));
        System.out.println(userData.hashCode());
    }
// 原生输出
false
// 没有 canEqual 方法
1625635731
// @EqualsAndHashCode 输出
true
true
355159

通过上面的输出对比 明显加注解后的结果 和 原生的equals 不一样,建议_谨慎使用_

可以使用 Idea 反编译下 看看生成的代码逻辑 这里就不展示了 有兴趣的可以自己试下

增加 @Data 注解

来看一下这个懒人注解 也是用的最广泛的注解 @Data

Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
  public java.lang.String getName();
  public int getAge();
  public boolean isGood();
  public void setName(java.lang.String);
  public void setAge(int);
  public void setGood(boolean);
  public boolean equals(java.lang.Object);
  protected boolean canEqual(java.lang.Object);
  public int hashCode();
  public java.lang.String toString();
}

反编译后可以看出 它是 @Getter @Setter @EqualsAndHashCode @ToString 的集合体

这里还是建议谨慎使用 主要是 @EqualsAndHashCode 注解生成的代码 会影响 equal 的判断

使用 @NoArgsConstructor
Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData();
}

反编译后 可以看到 和使用 @RequiredArgsConstructor 和没有注解一样的

使用 @AllArgsConstructor
Compiled from "UserData.java"
public class lombok.UserData {
  public lombok.UserData(java.lang.String, int, boolean);
}

反编译后 看出 没有无参数构造函数 增加一个全参数构造函数

使用 @Builder
编译后多了一个内部类 UserData$UserDataBuilder.class
Compiled from "UserData.java"
public class lombok.UserData$UserDataBuilder {
  lombok.UserData$UserDataBuilder();
  public lombok.UserData$UserDataBuilder name(java.lang.String);
  public lombok.UserData$UserDataBuilder age(int);
  public lombok.UserData$UserDataBuilder good(boolean);
  public lombok.UserData build();
  public java.lang.String toString();
}

Compiled from "UserData.java"
public class lombok.UserData {
  lombok.UserData(java.lang.String, int, boolean);
  public static lombok.UserData$UserDataBuilder builder();
}

生成了一个全参数构造函数 和 一个 builder 方法

参考

https://projectlombok.org/

javap -verbose UserData

Classfile /***/classes/lombok/UserData.class
  Last modified 2021-4-13; size 1975 bytes
  MD5 checksum 3fe9c971d14ecbcecdc5be0c02e7907e
  Compiled from "UserData.java"
public class lombok.UserData
  minor version: 0
  major version: 52 // 便衣使用的JDK版本  
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool: // 常量池
   #1 = Methodref          #22.#66        // java/lang/Object."<init>":()V
   #2 = Fieldref           #5.#67         // lombok/UserData.name:Ljava/lang/String;
   #3 = Fieldref           #5.#68         // lombok/UserData.age:I
   #4 = Fieldref           #5.#69         // lombok/UserData.good:Z
   #5 = Class              #70            // lombok/UserData
   #6 = Methodref          #5.#71         // lombok/UserData.canEqual:(Ljava/lang/Object;)Z
   #7 = Methodref          #5.#72         // lombok/UserData.getName:()Ljava/lang/String;
   #8 = Methodref          #22.#73        // java/lang/Object.equals:(Ljava/lang/Object;)Z
   #9 = Methodref          #5.#74         // lombok/UserData.getAge:()I
  #10 = Methodref          #5.#75         // lombok/UserData.isGood:()Z
  #11 = Methodref          #22.#76        // java/lang/Object.hashCode:()I
  #12 = Class              #77            // java/lang/StringBuilder
  #13 = Methodref          #12.#66        // java/lang/StringBuilder."<init>":()V
  #14 = String             #78            // UserData(name=
  #15 = Methodref          #12.#79        // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #16 = String             #80            // , age=
  #17 = Methodref          #12.#81        // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  #18 = String             #82            // , good=
  #19 = Methodref          #12.#83        // java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder;
  #20 = String             #84            // )
  #21 = Methodref          #12.#85        // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #22 = Class              #86            // java/lang/Object
  #23 = Utf8               name
  #24 = Utf8               Ljava/lang/String;
  #25 = Utf8               age
  #26 = Utf8               I
  #27 = Utf8               good
  #28 = Utf8               Z
  #29 = Utf8               <init>
  #30 = Utf8               ()V
  #31 = Utf8               Code
  #32 = Utf8               LineNumberTable
  #33 = Utf8               LocalVariableTable
  #34 = Utf8               this
  #35 = Utf8               Llombok/UserData;
  #36 = Utf8               getName
  #37 = Utf8               ()Ljava/lang/String;
  #38 = Utf8               getAge
  #39 = Utf8               ()I
  #40 = Utf8               isGood
  #41 = Utf8               ()Z
  #42 = Utf8               setName
  #43 = Utf8               (Ljava/lang/String;)V
  #44 = Utf8               setAge
  #45 = Utf8               (I)V
  #46 = Utf8               setGood
  #47 = Utf8               (Z)V
  #48 = Utf8               equals
  #49 = Utf8               (Ljava/lang/Object;)Z
  #50 = Utf8               o
  #51 = Utf8               Ljava/lang/Object;
  #52 = Utf8               other
  #53 = Utf8               this$name
  #54 = Utf8               other$name
  #55 = Utf8               StackMapTable
  #56 = Class              #70            // lombok/UserData
  #57 = Class              #86            // java/lang/Object
  #58 = Utf8               canEqual
  #59 = Utf8               hashCode
  #60 = Utf8               PRIME
  #61 = Utf8               result
  #62 = Utf8               $name
  #63 = Utf8               toString
  #64 = Utf8               SourceFile
  #65 = Utf8               UserData.java
  #66 = NameAndType        #29:#30        // "<init>":()V
  #67 = NameAndType        #23:#24        // name:Ljava/lang/String;
  #68 = NameAndType        #25:#26        // age:I
  #69 = NameAndType        #27:#28        // good:Z
  #70 = Utf8               lombok/UserData
  #71 = NameAndType        #58:#49        // canEqual:(Ljava/lang/Object;)Z
  #72 = NameAndType        #36:#37        // getName:()Ljava/lang/String;
  #73 = NameAndType        #48:#49        // equals:(Ljava/lang/Object;)Z
  #74 = NameAndType        #38:#39        // getAge:()I
  #75 = NameAndType        #40:#41        // isGood:()Z
  #76 = NameAndType        #59:#39        // hashCode:()I
  #77 = Utf8               java/lang/StringBuilder
  #78 = Utf8               UserData(name=
  #79 = NameAndType        #87:#88        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #80 = Utf8               , age=
  #81 = NameAndType        #87:#89        // append:(I)Ljava/lang/StringBuilder;
  #82 = Utf8               , good=
  #83 = NameAndType        #87:#90        // append:(Z)Ljava/lang/StringBuilder;
  #84 = Utf8               )
  #85 = NameAndType        #63:#37        // toString:()Ljava/lang/String;
  #86 = Utf8               java/lang/Object
  #87 = Utf8               append
  #88 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #89 = Utf8               (I)Ljava/lang/StringBuilder;
  #90 = Utf8               (Z)Ljava/lang/StringBuilder;
{
  public lombok.UserData();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable: // 源代码行号和字节码的对应关系
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Llombok/UserData;

  public java.lang.String getName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field name:Ljava/lang/String;
         4: areturn
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Llombok/UserData;

  public int getAge();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #3                  // Field age:I
         4: ireturn
      LineNumberTable:
        line 8: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Llombok/UserData;

  public boolean isGood();
    descriptor: ()Z
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #4                  // Field good:Z
         4: ireturn
      LineNumberTable:
        line 10: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Llombok/UserData;

  public void setName(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #2                  // Field name:Ljava/lang/String;
         5: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Llombok/UserData;
            0       6     1  name   Ljava/lang/String;

  public void setAge(int);
    descriptor: (I)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: iload_1
         2: putfield      #3                  // Field age:I
         5: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Llombok/UserData;
            0       6     1   age   I

  public void setGood(boolean);
    descriptor: (Z)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: iload_1
         2: putfield      #4                  // Field good:Z
         5: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Llombok/UserData;
            0       6     1  good   Z

  public boolean equals(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Z
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=5, args_size=2
         0: aload_1
         1: aload_0
         2: if_acmpne     7
         5: iconst_1
         6: ireturn
         7: aload_1
         8: instanceof    #5                  // class lombok/UserData
        11: ifne          16
        14: iconst_0
        15: ireturn
        16: aload_1
        17: checkcast     #5                  // class lombok/UserData
        20: astore_2
        21: aload_2
        22: aload_0
        23: invokevirtual #6                  // Method canEqual:(Ljava/lang/Object;)Z
        26: ifne          31
        29: iconst_0
        30: ireturn
        31: aload_0
        32: invokevirtual #7                  // Method getName:()Ljava/lang/String;
        35: astore_3
        36: aload_2
        37: invokevirtual #7                  // Method getName:()Ljava/lang/String;
        40: astore        4
        42: aload_3
        43: ifnonnull     54
        46: aload         4
        48: ifnull        65
        51: goto          63
        54: aload_3
        55: aload         4
        57: invokevirtual #8                  // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
        60: ifne          65
        63: iconst_0
        64: ireturn
        65: aload_0
        66: invokevirtual #9                  // Method getAge:()I
        69: aload_2
        70: invokevirtual #9                  // Method getAge:()I
        73: if_icmpeq     78
        76: iconst_0
        77: ireturn
        78: aload_0
        79: invokevirtual #10                 // Method isGood:()Z
        82: aload_2
        83: invokevirtual #10                 // Method isGood:()Z
        86: if_icmpeq     91
        89: iconst_0
        90: ireturn
        91: iconst_1
        92: ireturn
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      93     0  this   Llombok/UserData;
            0      93     1     o   Ljava/lang/Object;
           21      72     2 other   Llombok/UserData;
           36      57     3 this$name   Ljava/lang/Object;
           42      51     4 other$name   Ljava/lang/Object;
      StackMapTable: number_of_entries = 8
        frame_type = 7 /* same */
        frame_type = 8 /* same */
        frame_type = 252 /* append */
          offset_delta = 14
          locals = [ class lombok/UserData ]
        frame_type = 253 /* append */
          offset_delta = 22
          locals = [ class java/lang/Object, class java/lang/Object ]
        frame_type = 8 /* same */
        frame_type = 1 /* same */
        frame_type = 12 /* same */
        frame_type = 12 /* same */

  protected boolean canEqual(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Z
    flags: ACC_PROTECTED
    Code:
      stack=1, locals=2, args_size=2
         0: aload_1
         1: instanceof    #5                  // class lombok/UserData
         4: ireturn
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Llombok/UserData;
            0       5     1 other   Ljava/lang/Object;

  public int hashCode();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: bipush        59
         2: istore_1
         3: iconst_1
         4: istore_2
         5: aload_0
         6: invokevirtual #7                  // Method getName:()Ljava/lang/String;
         9: astore_3
        10: iload_2
        11: bipush        59
        13: imul
        14: aload_3
        15: ifnonnull     23
        18: bipush        43
        20: goto          27
        23: aload_3
        24: invokevirtual #11                 // Method java/lang/Object.hashCode:()I
        27: iadd
        28: istore_2
        29: iload_2
        30: bipush        59
        32: imul
        33: aload_0
        34: invokevirtual #9                  // Method getAge:()I
        37: iadd
        38: istore_2
        39: iload_2
        40: bipush        59
        42: imul
        43: aload_0
        44: invokevirtual #10                 // Method isGood:()Z
        47: ifeq          55
        50: bipush        79
        52: goto          57
        55: bipush        97
        57: iadd
        58: istore_2
        59: iload_2
        60: ireturn
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      61     0  this   Llombok/UserData;
            3      58     1 PRIME   I
            5      56     2 result   I
           10      51     3 $name   Ljava/lang/Object;
      StackMapTable: number_of_entries = 4
        frame_type = 255 /* full_frame */
          offset_delta = 23
          locals = [ class lombok/UserData, int, int, class java/lang/Object ]
          stack = [ int ]
        frame_type = 255 /* full_frame */
          offset_delta = 3
          locals = [ class lombok/UserData, int, int, class java/lang/Object ]
          stack = [ int, int ]
        frame_type = 91 /* same_locals_1_stack_item */
          stack = [ int ]
        frame_type = 255 /* full_frame */
          offset_delta = 1
          locals = [ class lombok/UserData, int, int, class java/lang/Object ]
          stack = [ int, int ]

  public java.lang.String toString();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: new           #12                 // class java/lang/StringBuilder
         3: dup
         4: invokespecial #13                 // Method java/lang/StringBuilder."<init>":()V
         7: ldc           #14                 // String UserData(name=
         9: invokevirtual #15                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        12: aload_0
        13: invokevirtual #7                  // Method getName:()Ljava/lang/String;
        16: invokevirtual #15                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        19: ldc           #16                 // String , age=
        21: invokevirtual #15                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        24: aload_0
        25: invokevirtual #9                  // Method getAge:()I
        28: invokevirtual #17                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        31: ldc           #18                 // String , good=
        33: invokevirtual #15                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        36: aload_0
        37: invokevirtual #10                 // Method isGood:()Z
        40: invokevirtual #19                 // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder;
        43: ldc           #20                 // String )
        45: invokevirtual #15                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        48: invokevirtual #21                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        51: areturn
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      52     0  this   Llombok/UserData;
}
SourceFile: "UserData.java"

到此,相信大家对“Lombok的功能是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI