Lombok快速入门
1. 什么是lombok
官网原话 :
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Lombk是一个java库 , 它可以自动注入到你的编辑器与构建工具中 , 从而对java进行增强 .
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
通过一个注解 , 你的类就即可获得一个功能齐全的构建器 , 不用再重写
getter
和equals
方法(自动生成) , 以及会自动为你生成一个用于记录日志的logger变量 与 其他更多功能 。
总的来说 , lombok就是一个java库 , 可以通过使用lombok提供的注解 , 从而可以省略一些重复代码的编写 , 例如getter , setter , equals 等方法的编写. 添加相关注解之后 , 会在编译阶段自动为我们生成 , 从而提高了代码可读性.
2. 使用准备
Maven项目中引入如下依赖 :
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
视情况还需要在IDE中安装lombok的插件 (这里以IDEA为例) :
1552065874909.png
安装完重启IDEA , 勾选如下配置 :
1552149258772.png
3. 常用注解解析
@NotNull
-
作用 : 避免空指针异常 , 当被标识的变量为null时 , 会自动抛出
NullPointerException
-
作用位置 : 成员变量 , 方法形参
-
代码示例 :
使用
@NotNull
:@Getter @Setter @NonNull private List<Person> members;
等价的java源代码 :
@NonNull private List<Person> members; public Family(@NonNull final List<Person> members) { if (members == null) throw new java.lang.NullPointerException("members"); this.members = members; } @NonNull public List<Person> getMembers() { return members; } //上面Members属性同时使用了@NotNull与@Setter,相当于在setter方法中在形参前添加@NotNull注解 //在形参前添加@NotNull相当于对形参进行空值判断 public void setMembers(@NonNull final List<Person> members) { if (members == null) { throw new java.lang.NullPointerException("members"); } this.members = members; }
@Cleanup
-
作用 : 自动帮我们调用资源对象的
close()
方法 -
作用位置 : 资源对象变量上
-
代码示例 :
使用
@Cleanup
注解 :public void testCleanUp() { try { @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(new byte[] {'Y','e','s'}); System.out.println(baos.toString()); } catch (IOException e) { e.printStackTrace(); } }
等价的java源代码 :
public void testCleanUp() { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { baos.write(new byte[]{'Y', 'e', 's'}); System.out.println(baos.toString()); } finally { baos.close(); } } catch (IOException e) { e.printStackTrace(); } }
@Getter & @Setter
-
作用 :
-
@Getter
: 生成对应的getter方法 -
@Setter
: 生成对应的setter方法
-
-
作用位置 : 成员变量上
-
代码示例 :
使用
@Getter
与@Setter
:@Getter @Setter private boolean employed = true; @Setter(AccessLevel.PROTECTED) private String name; // AccessLevel.PROTECTED指定生成的构造方法的权限修饰符为protected
等价的java源代码 :
private boolean employed = true; private String name; public boolean isEmployed() { return employed; } public void setEmployed(final boolean employed) { this.employed = employed; } protected void setName(final String name) { this.name = name; }
@EqualsAndHashCode
-
作用 : 根据成员变量生成
equals()
与hashCode()
- 作用位置 : 类上
-
常用属性 :
-
exclude
: 指定要排除的属性 ; -
of
: 指定根据哪些属性生成equals()
与hashCode()
方法; -
callSuper
: 该值为true
时 , 生成的equals()
与hashCode()
调用父类的equals()
与hashCode()
方法 , 默认值为false
;
-
@NoArgsConstructor & @AllArgsConstructor & @RequiredArgsConstructor
-
作用 :
-
@NoArgsConstructor
: 自动生成无参构造方法 ; -
@AllArgsConstructor
: 自动生成全参的构造方法 ; -
@RequiredArgsConstructor
: 对标识了@NotNull
或者是final
关键字的成员变量生成权限为private
的构造方法 , 如何想要对外提供使用可以指定staticName
属性生成一个static方法 ;
-
-
作用位置 : 均在类上
-
代码示例 :
使用lombok注解 :
import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.AllArgsConstructor; import lombok.NonNull; @RequiredArgsConstructor(staticName = "of") //生成一个static方法,方法名为of @AllArgsConstructor(access = AccessLevel.PROTECTED) public class ConstructorExample<T> { private int x, y; @NonNull private T description; @NoArgsConstructor public static class NoArgsExample { @NonNull private String field; } }
等价的java源码 :
public class ConstructorExample<T> { private int x, y; @NonNull private T description; private ConstructorExample(T description) { if (description == null) throw new NullPointerException("description"); this.description = description; } public static <T> ConstructorExample<T> of(T description) { return new ConstructorExample<T>(description); } @java.beans.ConstructorProperties({"x", "y", "description"}) protected ConstructorExample(int x, int y, T description) { if (description == null) throw new NullPointerException("description"); this.x = x; this.y = y; this.description = description; } public static class NoArgsExample { @NonNull private String field; public NoArgsExample() { } } }
@Data
-
作用 : 自动为所有字段添加
@ToString
,@EqualsAndHashCode
,@Getter
方法,为<font style="color:red">非final字段 </font>添加@Setter
, 以及在类上添加@RequiredArgsConstructor
-
作用位置 : 类上
-
代码示例 :
使用
@Data
注解 :@Data(staticConstructor="of") public class Company { private final Person founder; private String name; private List<Person> employees; }
等价的java源代码 :
public class Company { private final Person founder; private String name; private List<Person> employees; private Company(final Person founder) { this.founder = founder; } //对应staticConstructor="of" public static Company of(final Person founder) { return new Company(founder); } public Person getFounder() { return founder; } public String getName() { return name; } public void setName(final String name) { this.name = name; } public List<Person> getEmployees() { return employees; } public void setEmployees(final List<Person> employees) { this.employees = employees; } @java.lang.Override public boolean equals(final java.lang.Object o) { if (o == this) return true; if (o == null) return false; if (o.getClass() != this.getClass()) return false; final Company other = (Company)o; if (this.founder == null ? other.founder != null : !this.founder.equals(other.founder)) return false; if (this.name == null ? other.name != null : !this.name.equals(other.name)) return false; if (this.employees == null ? other.employees != null : !this.employees.equals(other.employees)) return false; return true; } @java.lang.Override public int hashCode() { final int PRIME = 31; int result = 1; result = result * PRIME + (this.founder == null ? 0 : this.founder.hashCode()); result = result * PRIME + (this.name == null ? 0 : this.name.hashCode()); result = result * PRIME + (this.employees == null ? 0 : this.employees.hashCode()); return result; } @java.lang.Override public java.lang.String toString() { return "Company(founder=" + founder + ", name=" + name + ", employees=" + employees + ")"; } }
@Slf4j
-
作用 : 自动生成一个Logger的对象
-
作用位置 : 类上
-
代码示例 :
import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Slf4j public class Slf4jTest { //@Slf4j等价于如下代码 //private final Logger log = LoggerFactory.getLogger(Slf4jTest.class); @Test public void slfTest() { log.debug("testing"); } }
@Accessors
-
作用 : 通过该注解可以控制
getter
与setter
的命名与返回值 ; -
作用位置 : 类上
-
属性 :
-
fluent
: 默认值为false , 当fluent
的值为true时 ,@Data
注解生成的getter
与setter
的方法名均为对应的成员变量名 , 且setter
的返回值为当前当前对象 , 如下所示;@Data @Accessors(fluent = true) class User { private Integer id; private String name; // 生成的getter和setter方法如下,方法体略 public Integer id(){} public User id(Integer id){} public String name(){} public User name(String name){} }
-
chain
: 默认值为false , 当chain
的值为true时 ,@Data
注解生成的setter
的返回值为当前对象 , 相当于开启链式编程的开关 , 代码如下所示 ;@Data @Accessors(chain = true) class User { private Integer id; private String name; // 生成的setter方法如下,setter返回的是当前User对象 , 方法体略 public User setId(Integer id){} public User setName(String name){} }
-
prefix
: 默认值为{} , 若指定prefix
的值 , 则生成的getter
与setter
名为属性名 , 且会忽略其指定的前缀同时遵循驼峰命名原则 , 如下代码所示@Data @Accessors(prefix = "f") class User { private Integer fId; //属性名带f private String fName; // 生成的getter和setter方法如下,方法体略 public Integer id(){} // 生成的方法名为属性名去掉前缀 public void id(Integer id){} public String name(){} public void name(String name){} }
-
参考链接 :
[lombok @EqualsAndHashCode 注解的影响]:https://blog.csdn.net/zhanlanmg/article/details/50392266
[官方文档]:https://projectlombok.org/features/all
[Lombok介绍及使用方法]:https://www.cnblogs.com/holten/p/5729226.html