本篇内容主要讲解“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 的无参数默认构造器
在类 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 方法
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 变量方法
Compiled from "UserData.java"
public class lombok.UserData {
public lombok.UserData();
}
反编译后 可以看到 和没有注解是一样的 生成一个 无参数构造函数
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)
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
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 的判断
Compiled from "UserData.java"
public class lombok.UserData {
public lombok.UserData();
}
反编译后 可以看到 和使用 @RequiredArgsConstructor 和没有注解一样的
Compiled from "UserData.java"
public class lombok.UserData {
public lombok.UserData(java.lang.String, int, boolean);
}
反编译后 看出 没有无参数构造函数 增加一个全参数构造函数
编译后多了一个内部类 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的功能是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/c8d8z8/blog/5017502