服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 详解Lombok快速上手(安装、使用与注解参数)

详解Lombok快速上手(安装、使用与注解参数)

2021-06-21 13:40上帝爱吃苹果-Soochow Java教程

这篇文章主要介绍了详解Lombok快速上手(安装、使用与注解参数) ,这里整理了一些日常编码中能遇到的所有关于它的使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

lombok插件安装与使用说明

在实习中发现项目中ide一直报检查错误,原来是使用了lombok注解的黑科技,这里整理了一些日常编码中能遇到的所有关于它的使用详解,其实lombok项目的产生就是为了省去我们手动创建getter和setter方法等等一些基本组件代码的麻烦,它能够在我们编译源码的时候自动帮我们生成getter和setter方法。即它最终能够达到的效果是:在源码中没有getter和setter等组件方法,但是在编译生成的字节码文件中有getter和setter等组件方法。

常见参数

  • @setter 注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
  • @getter 使用方法同上,区别在于生成的是getter方法。
  • @tostring 注解在类,添加tostring方法。
  • @equalsandhashcode 注解在类,生成hashcode和equals方法。
  • @noargsconstructor 注解在类,生成无参的构造方法。
  • @requiredargsconstructor 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@nonnull注解的字段。
  • @allargsconstructor 注解在类,生成包含类中所有字段的构造方法。
  • @data 注解在类,为类的所有字段注解@tostring、@equalsandhashcode、@getter的便捷方法,同时为所有非final字段注解@setter。

lombok的依赖于安装

依赖管理

?
1
2
3
4
5
<dependency>
 <groupid>org.projectlombok</groupid>
 <artifactid>lombok</artifactid>
 <version>1.16.20</version>
</dependency>

idea插件的安装

如果ide没有安装插件的话会提示错误,而且不会有代码提示,所以ide要安装插件

  1. 在idea插件里搜索lombok,安装,重启
  2. 直接官网下载插件,安装,这是链接
  3. 设置中启用annotation processors

详解Lombok快速上手(安装、使用与注解参数)@data

@data小例子

平时在使用时最常用@data注解

@data可以很好地处理字段的泛型参数。 为了在为具有泛型的类构造对象时减少样板,可以使用staticconstructor参数来生成私有构造函数,以及返回新实例的静态方法。 这样,javac将推断变量名称。 因此,通过这样声明:@data(staticconstructor =“of”)类foo {private t x;}可以通过写入来创建foo的新实例:foo.of(5); 而不必写:new foo (5);

如果使用了@data注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@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;
 }
}

不加lombok注解的pojo的写法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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;
 }
 
 //可以看到这里自动生成了of方法
 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;
 }
 }
}

扩展@tostring

任何类定义都可以用@tostring注释,让lombok生成tostring()方法的实现。默认情况下,它会按顺序打印类名以及每个字段,并以逗号分隔。

通过将includefieldnames参数设置为true,您可以为tostring()方法的输出更详细(但也有一些长度)。这是默认的

默认情况下,将打印所有非静态字段。如果要跳过某些字段,可以使用@ tostring.exclude注释这些字段。或者,您可以使用@tostring(onlyexplicitlyincluded = true)准确指定要使用的字段,然后使用@ tostring.include标记要包含的每个字段。

通过将callsuper设置为true,可以将tostring的超类实现的输出包含到输出中。但是java.lang.object中tostring()的默认实现几乎毫无意义,因此除非扩展另一个类,否则不要这样做。

还可以在tostring中包含方法调用的输出。只能包含不带参数的实例(非静态)方法。为此,请使用@tostring.include标记方法。

可以使用@tostring.include(name =“some other name”)更改用于标识成员的名称,并且可以通过@tostring.include(rank = -1)更改成员的打印顺序。没有等级的成员被认为具有等级0,更高等级的成员被首先打印,并且相同等级的成员以它们在源文件中出现的相同顺序被打印。

tostring小例子:

加注解:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@tostring
public class tostringexample {
 private static final int static_var = 10;
 private string name;
 private shape shape = new square(5, 10);
 private string[] tags;
 @tostring.exclude private int id;
 
 public string getname() {
 return this.name;
 }
 
 @tostring(callsuper=true, includefieldnames=true)
 public static class square extends shape {
 private final int width, height;
 
 public square(int width, int height) {
  this.width = width;
  this.height = height;
 }
 }
}

等效于:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class tostringexample {
 private static final int static_var = 10;
 private string name;
 private shape shape = new square(5, 10);
 private string[] tags;
 private int id;
 
 public string getname() {
 return this.getname();
 }
 
 public static class square extends shape {
 private final int width, height;
 
 public square(int width, int height) {
  this.width = width;
  this.height = height;
 }
 
 @override public string tostring() {
  return "square(super=" + super.tostring() + ", width=" + this.width + ", height=" + this.height + ")";
 }
 }
 
 @override public string tostring() {
 return "tostringexample(" + this.getname() + ", " + this.shape + ", " + arrays.deeptostring(this.tags) + ")";
 }
}

构造器注解扩展

@noargsconstructor

此注释主要与@data或生成注释的其他构造函数组合使用。

@noargsconstructor将生成一个没有参数的构造函数。如果这是不可能的(因为最终字段),将导致编译器错误,除非使用@noargsconstructor(force = true),然后使用0 / false / null初始化所有final字段。对于具有约束的字段,例如@nonnull字段,不会生成任何检查,因此请注意,在稍后正确初始化这些字段之前,通常不会满足这些约束。某些java构造(例如hibernate和service provider interface)需要no-args构造函数。

@requiredargsconstructor

@requiredargsconstructor为每个需要特殊处理的字段生成一个带有1个参数的构造函数。所有未初始化的final字段都会获得一个参数,以及标记为@nonnull的任何字段,这些字段在声明它们时未初始化。对于标有@nonnull的字段,还会生成显式空检查。如果用于标记为@nonnull的字段的任何参数包含null,则构造函数将抛出nullpointerexception。参数的顺序与字段在类中的显示顺序相匹配。

@allargsconstructor

@allargsconstructor为类中的每个字段生成一个带有1个参数的构造函数。标有@nonnull的字段会导致对这些参数进行空检查。

这些注释中的每一个都允许使用替代形式,其中生成的构造函数始终是私有的,并且生成包围私有构造函数的附加静态工厂方法。通过为注释提供staticname值来启用此模式,如下所示:@requiredargsconstructor(staticname =“of”)。与普通构造函数不同,这种静态工厂方法将推断泛型。这意味着您的api用户可以编写mapentry.of(“foo”,5)而不是更长的新mapentry <string,integer>(“foo”,5)。

与大多数其他lombok注释不同,显式构造函数的存在不会阻止这些注解生成自己的构造函数。这意味着可以编写自己的专用构造函数,并让lombok生成样板文件。

注意:如果出现冲突(自定义的一个构造函数最终使用与lombok生成的构造函数相同),则会发生编译器错误。

@log及其他日志注解

就是简化了生成log的代码,直接看例子

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@log
public class logexample {
 
 public static void main(string... args) {
 log.severe("something's wrong here");
 }
}
 
@slf4j
public class logexampleother {
 
 public static void main(string... args) {
 log.error("something else is wrong here");
 }
}
 
@commonslog(topic="counterlog")
public class logexamplecategory {
 
 public static void main(string... args) {
 log.error("calling the 'counterlog' with a message");
 }
}

等效于:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class logexample {
 private static final java.util.logging.logger log = java.util.logging.logger.getlogger(logexample.class.getname());
 
 public static void main(string... args) {
 log.severe("something's wrong here");
 }
}
 
public class logexampleother {
 private static final org.slf4j.logger log = org.slf4j.loggerfactory.getlogger(logexampleother.class);
 
 public static void main(string... args) {
 log.error("something else is wrong here");
 }
}
 
public class logexamplecategory {
 private static final org.apache.commons.logging.log log = org.apache.commons.logging.logfactory.getlog("counterlog");
 
 public static void main(string... args) {
 log.error("calling the 'counterlog' with a message");
 }
}

资料链接

想要更详细的了解lombok,推荐查看它的github来阅读更多的使用特性

lombok的github链接

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/keeya/p/9929617.html

延伸 · 阅读

精彩推荐