一、常用注解(以下注解可根据需要一起搭配使用!)
1、@Data(类级)
- Data注解集合了Getter、Setter、RequiredArgsConstructor、EqualsAndHashCode、ToString的合力体现,提供类所有属性的 get 和 set 方法,此外还提供了equals、canEqual、hashCode、toString 方法。
案例:
@ToString
@Data(staticConstructor = “aaaa”)
public class DD {
@NonNull
final private Integer a;
@NonNull
private Integer b;
final private Integer c;
private String lombok;
}

2、@Getter/@Setter(属性级、类级)
- 属性级:为单个变量赋予get、set方法。默认生成public方法,我们也可以指定访问权限等级。
- 类级:若注解在类上,则默认所有非静态的变量都生成get、set方法,同样可以通过注释来实现禁止生成的功能:
案例1:属性级
public class Test{
@Getter @Setter(AccessLevel.PUBLIC)
private String lombok;
}

案例2:类级
@Setter
@Getter
public class DD {
@Setter(AccessLevel.NONE)
private String lombok;
}

3、@ToString(类级)
- 该注解应用在类上,为我们生成Object的toString方法,而该注解里面的几个属性能更加丰富我们想要的内容,exclude属性禁止在toString方法中使用某字段,而of可以指定需要使用的字段:
-
这个注解用在 类 上,可以生成所有参数的 toString 方法,还会生成默认的构造方法。
案例:类级
@Getter
@Setter
@ToString(exclude = {“a”, “b”}, of = {“c”, “lombok”})
public class DD {
private Integer a;
private Integer b;
private Integer c;
private String lombok;
public static void main(String[] args) {
DD dd = new DD();
System.out.println(dd.toString());
}
}

注意:DD(c=null, lombok=null)
4、@EqualsAndHashCode(类级)
- 该注解应用在类上,使用该注解,lombok会为我们生成 equals、canEqual、hashCode 方法,包括所有非静态属性和非transient的属性;同样可以使用exclude属性禁止在toString方法中使用某字段,而of可以指定需要使用的字段;也可以通过callSuper属性在重写的方法中使用父类的字段,这样我们可以更加灵活的定义bean的比对,如下图:

5、@NonNull(方法、构造函数的参数或者属性上
- 该注解应用在方法或构造器的参数上或者属性上,用来判断参数的合法性,默认抛出NPE异常。
-
注解在 属性 上,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常,也会有一个默认的无参构造方法。
案例:
@Getter
@Setter
@ToString
public class DD {
private Integer a;
private Integer b;
private Integer c;
private String lombok;
public DD(@NonNull Integer a, Integer b, Integer c, String lombok) {
this.a = a;
this.b = b;
this.c = c;
this.lombok = lombok;
}
public static void main(String[] args) {
DD a1 = new DD(1, 2, 3, "a");
DD a2 = new DD(null, 2, 3, "a");
System.out.println(a1.toString()+"\n"+a2.toString());
}
}


6、@NoArgsConstructor(类级)
- 为我们生成无参构造器。
- 默认情况下,RequiredArgsConstructor、AllArgsConstructor生成的构造函数会对@NonNull注解的属性进行非空校验。

7、@RequiredArgsConstructor(类级)
- 为我们生成指定参数构造器。
-
这个注解用在 类 上,使用类中所有带有 @NonNull 注解的或者带有 final 修饰的成员变量生成对应的构造方法。
- 默认情况下,RequiredArgsConstructor、AllArgsConstructor生成的构造函数会对@NonNull注解的属性进行非空校验。
- 主要对于字段类型是final和使用@NonNull注解标注的属性来生成构造函数;同时可以通过staticName来指定静态方法来构造对象。
案例:
@Getter
@Setter
@ToString
@RequiredArgsConstructor(staticName = “getStaticConstruct”)
public class DD {
@NonNull
final private Integer a;
@NonNull
private Integer b;
final private Integer c;
private String lombok;
}


8、@AllArgsConstructor(类级)
- 为我们生成包含所有参数的构造器,加了这个注解后,类中不提供默认构造方法了。
- 默认情况下,RequiredArgsConstructor、AllArgsConstructor生成的构造函数会对@NonNull注解的属性进行非空校验。

7、@Builder
- 函数式编程或者说流式的编程越来越流行,应用在大多数语言中,让程序更具简洁,可读性更高,编写更连贯,@Builder就带来了这个功能,生成一系列的build API,该注解也需要应用在类上
案例:
@ToString
@Data(staticConstructor = “aaaa”)
@Builder
public class DD {undefined
@NonNull
final private Integer a;
@NonNull
private Integer b;
final private Integer c;
private String lombok;
public static void main(String[] args) {
DD.builder().a(1).b(2).build();
}
}
8、@Log(类级)
- 该注解需要应用到类上,在编写服务层,需要添加一些日志,以便定位问题,我们通常会定义一个静态常量Logger,然后应用到我们想输出日志的地方,现在一个注解就可以实现
案例:
@Data(staticConstructor = “aaaa”)
@Builder
@Log
@AllArgsConstructor
public class DD {undefined
@NonNull
final private Integer a;
@NonNull
private Integer b;
final private Integer c;
private String lombok;
public DD(@NonNull Integer a, @NonNull Integer b, Integer c) {
log.info("ppppp");
this.a = a;
this.b = b;
this.c = c;
}
public static void main(String[] args) {
DD b = new DD(1,2,3);
System.out.println(b);
}
}

9、@val
- 这个注解用在 类 上,会生成含所有参数的构造方法,get 方法,此外还提供了equals、hashCode、toString 方法。
- 熟悉JS的同学都知道,var可以定义任何类型的变量,而在JAVA的视线中,我们需要制定具体变量的类型,而val让我们摆脱指定,编译后就精确匹配上类型,默认是final类型,就像java8中的函数式表达一样,()->System.out.println(“hello lombok”); 就可以解析到Runnable函数式接口。
- 编译后,可以精确的定位类型。

案例:
JAVA文件:
var map = new HashMap<String,String>();
map.put(“1”,“2”);
map.put(“2”,“3”);
map.put(“3”,“4”);
System.out.println(map.toString());
CLASS文件:
public static void main(String[] args) {undefined
HashMap<String, String> map = new HashMap();
map.put(“1”, “2”);
map.put(“2”, “3”);
map.put(“3”, “4”);
System.out.println(map.toString());
}
10、@Cleanup(变量前面)
- 这个注解用在 变量 前面,可以保证此变量代表的资源会被自动关闭,默认是调用资源的 close() 方法,如果该资源有其它关闭方法,可使用 @Cleanup(“methodName”) 来指定要调用的方法,也会生成默认的构造方法
- 当我们对流进行操作,我们通常需要调用close方法来关闭或结束某资源,而@CleanUp注解可以帮我们调用close方法,并且放到try/catch块中进行处理,如下图:

JAVA文件:
public static void main(String[] args) {undefined
try {
@Cleanup var inputStream = new FileInputStream(args[0]);
inputStream.read();
} catch (Exception e) {undefined
e.printStackTrace();
}
}
CLASS文件:
public static void main(String[] args) {undefined
try {
FileInputStream inputStream = new FileInputStream(args[0]);
try {
inputStream.read();
} finally {
if (Collections.singletonList(inputStream).get(0) != null) {
inputStream.close();
}
}
} catch (Exception var6) {
var6.printStackTrace();
}
其实在 JDK1.7 之后就有了 try-with-resource,不用我们显式的关闭流:
public class AA implements AutoCloseable{
public void ss(){
System.out.println("ss");
}
@Override
public void close() throws Exception {
System.out.println("close");
}
}
// 调用aa,测试关闭
public static void main(String[] args) {
try (
var aa = new AA()) {
aa.ss();
} catch (Exception e) {undefined
e.printStackTrace();
}
}
结果:
ss
close
11、@Slf4j(类)
- 注解在 类 上;为类提供一个 属性名为 log 的 slf4j 日志对象,提供默认构造方法。

12、@SneakyThrows(方法上)
- 这个注解用在 方法 上,可以将方法中的代码用 try-catch 语句包裹起来,捕获异常并在 catch 中用 Lombok.sneakyThrow(e) 把异常抛出,可以使用 @SneakyThrows(Exception.class) 的形式指定抛出哪种异常,也会生成默认的构造方法。

13、@Synchronized (类方法 或者 实例方法 上)
这个注解用在 类方法 或者 实例方法 上,效果和 synchronized 关键字相同,区别在于锁对象不同,对于类方法和实例方法:
synchronized 关键字的锁对象分别是类的 class 对象和 this 对象,
而 @Synchronized 的锁对象分别是 私有静态 final 对象 lock 和 私有 final 对象 lock,当然,也可以自己指定锁对象,此外也提供默认的构造方法。
二、工具需求调研、设计思想
在JAVA应用程序中存在许多重复相似的、生成之后几乎不对其做更改的代码,但是我们还不得不花费很多精力编写它们来满足JAVA的编译需求。比如在JAVA应用程序的开发中,我们几乎要为所有Bean的成员变量添加get()、set()方法,这些相对固定但又不得不写的代码实在浪费精力,同时让类看起来更加的杂乱。
在项目开发阶段,一个class的属性是一直变化的,今天可能增加一个字段,明天可能删除一个字段。每次变化都需要修改对应的模板代码。另外,有的class的字段超级多,多到一眼看不完。如果加上模板代码,更难一眼看出来。更有甚者,由于字段太多,想要使用builder来创建。手动创建builder和字段和原来的类夹杂在一起,看起来真的难受。lombok的@Builder即可解决这个问题。
官方介绍:Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again. Early access to future java features such as val, and much more.
直白的说:Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。
三、工具工作原理、运行流程、实现方法
lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码。
可以看到,以Data注解为例,其应用于编译阶段的【.java->.class】,所以一般IDEA无法自动识别。所以这就是为什么在IDEA中我们使用Lombok的时候需要下载Lombok插件了。
说道 Lombok,我们就得去提到 JSR 269: Pluggable Annotation Processing API (www.jcp.org/en/jsr/deta…) 。JSR 269 之前我们也有注解这样的神器,可是我们比如想要做什么必须使用反射,反射的方法局限性较大。首先,它必须定义**@Retention为RetentionPolicy.RUNTIME**,只能在运行时通过反射来获取注解值,使得运行时代码效率降低。其次,如果想在编译阶段利用注解来进行一些检查,对用户的某些不合理代码给出错误报告,反射的使用方法就无能为力了。而 JSR 269 之后我们可以在 Javac的编译期利用注解做这些事情。所以我们发现核心的区分是在 运行期 还是 编译期。
应用于编译阶段的lombok注解@Data:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {}
对比,RestFul的注解@RestController是在运行期通过反射来实现业务逻辑:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {}
Lombok的基本操作流程是这样的:
1 定义编译期的注解
2 利用JSR269 api(Pluggable Annotation Processing API )创建编译期的注解处理器
3 利用tools.jar的javac api处理AST(抽象语法树)
4 将功能注册进入jar包


上图是 Lombok 处理流程,在Javac 解析成抽象语法树之后(AST), Lombok 根据自己的注解处理器,动态的修改 AST,增加新的节点(所谓代码),最终通过分析和生成字节码。
自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。
四、工具常用配置
1、添加依赖
在自己的项目里添加 lombok 的编译支持,在 pom 文件里面添加 dependency
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>x.x.x</version>
<scope>provided</scope>
</dependency>
2、idea中添加插件(必须)
打开 IDEA 的 Settings 面板,并选择 Plugins 选项,然后点击 “Browse repositories”
在输入框输入”lombok”,得到搜索结果,点击安装,然后安装提示重启 IDEA,安装成功;

已经添加依赖为什么还要安装idea的Lombok插件?现在有一个A类,其中有一些字段,没有创建它们的setter和getter方法,使用了lombok的@Data注解,另外有一个B类,它调用了A类实例的相应字段的setter和getter方法。编译A类和B类所在的项目,并不会报错,因为最终生成的A类字节码文件中存在相应字段的setter和getter方法。但是,IDE发现B类源代码中所使用的A类实例的setter和getter方法在A类源代码中找不到定义,IDE会认为这是错误。要解决以上这个不是真正错误的错误,所以需要下载安装Intellij Idea中的"Lombok plugin"。
3、lombok踩坑系列
同时使用lombok的@Data和@Builder注解时lombok默认只会生成全参构造器 这个时候使用mybatis等orm框架就是无法完成创建对象
如果使用Mybatis无法映射到对象上面 最好打开这个对象的字节码文件看一眼看看这个类的具体情况 会不会是没有无参的构造方法
五、参考
Lombok最全使用详解_runlion_123的博客-优快云博客_lombok高级用法
史上最全Lombok——看这篇就够了_weixin_41438466的博客-优快云博客
2037

被折叠的 条评论
为什么被折叠?



