听说隔壁用 Lombok 的六点就下班了,我也想六点下班!

好的,那么这篇文章就介绍下什么是 LombokLombok 做了什么以及 Lombok 是怎么做的

在介绍之前,先通过是否使用 Lombok 的效果来看下对比,首先来看下没有 Lombok 之前,我们的一个简单的 Java 对象(POJO)是长什么样子的:

哦,我的天啊,居然 60 行,好长啊!那我们接下来使用的 Lombok 来试下:

什么,只使用了 @Date 注解就可以实现之前 60 行的相同功能,代码长度整整缩小了 3 倍,这么神奇的嘛?那么让我们走进 Lombok 吧!

什么是 Lombok?

下面是 Lombok 官网的简介:

简而言之就是 Lombok 是一个很方便的插件,本质是个 Java 库,使用它通过相关注解就可以不用再编写冗长的 getter 或者 equals 等方法了。

接下来讲下 Lombok 实现的原理,这样就知道为什么要这样使用 Lombok 的注解了。

Lombok 实现原理

要讲 Lombok 的实现原理,在此之前就需要来说下注解的两种解析方式:运行时注解编译时注解

首先来看下运行时解析,比如 Spring 配置的 AOP 切面这些注解都是在程序运行的时候通过反射来获取的注解值,但是只有在程序运行时才能获取到这些注解值,导致运行时代码效率很低,并且如果想在编译阶段利用这些注解来进行检查,比如对用户的不合理代码作出错误报告,反射的方法就行不通了。

这就引出了第二种在编译时解析,Lombok 工具就是运行在编译时解析的。

那如何把注解与 Java 编译器结合使用呢?Java 也提供了两种解决方案:

第一种方案是注解处理器(Annotation Processing Tool),它最早是在 JDK 1.5 与注解(Annotation) 一起引入的,它是一个命令行工具,能够提供构建时基于源代码对程序结构的读取功能,能够通过运行注解处理器来生成新的中间文件,进而影响编译过程,不过它在 JDK 1.8 中被移除了,取而代之的是 JSR 269 插入式注解处理器(Pluggable Annotation Processing API),它是实现了 JSR 269 的机制,作为注解处理器的替代方案。

我们通过一个流程图来进一步说明注解处理器的工作原理:

首先写完代码后会调用 javac 编译,在编译后会生成抽象语法树(AST),之后会调用插入式注解处理器处理,上面说了插入式注解处理器会修改语法树,生成一些额外的代码,经过处理器的处理语法树会有变动,有变动之后,会再次到生成抽象语法树的处理环节,将变动后的代码再次生成抽象语法树,接着再通过注解处理器,如果这次语法树没有被修改,那么就会生成响应的字节码,变成 class 文件,以上就是整个注解处理器在整个 javac 编译源代码生成 class 文件中起到的作用。

在简单了解了 Lombok 实现原理后,让我们看下 Lombok 有哪些常见的注解:

Lombok 注解

下面是整理的常用的 Lombok 注解思维导图:

右侧上方的 @Getter、@Setter、@ToString、@EqualsAndHashCode 这几个名字大家都不陌生,无非就是帮我们生成对应的方法,这四个注解的总和也就是刚开始用的注解 @Data,这些注解都归结为常见方法的注解。

右侧下方的 @AllArgsConstructor、@RequiredArgsConstructor、@NoArgsConstructor 分别为全参构造函数、必须参数构造函数、无参构造函数,它们通常为构造方法的注解。

左侧的 @NonNull 会自动生成空值校验;@CleanUp 会自动调用变量的 close 方法释放资源;@Builder 会自动生成构造者模式,方便对属性 set/get 操作; @Synchronized 会自动生成同步锁;@SneakyThrows 会自动生成 try/catch 捕捉异常;@Slf4j 是日志相关的,会自动为类添加日志支持。

以上就是 Lombok 为我们提供的比较常用的注解。

Lombok 使用

首先需要安装 Lombok 插件,我在这里是以 IDEA 2019.3.1 版本来演示的:

安装 Lombok 插件

点击 File->Settings->Plugins,搜索 Lombok,然后点击安装 Lombok 插件:

在安装完插件后重启 IDEA,到此 Lombok 插件就安装完成了,接下来就要进行实践演示了:

Lombok 常用注解演示

首先在 pom 文件中引入依赖:

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>

其中 <scope>provided</scope> 表示 jar 包是运行在编译时的,当程序编译成 class 源代码后,这个 jar 包就不会在源代码层面有所体现。

接下来演示 Lombok 注解使用方式,并通过查看编译后 class 文件,理解其工作原理,在这里以 @Getter 注解为例:

首先创建一个 GetterDemo 类,其中有 nameage 两个字段。

package com.wupx.lombok;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull; public class GetterDemo { @Getter(value = AccessLevel.PRIVATE, onMethod_ = {@NonNull})
private String age; @Getter(lazy = true)
private final String name = "wupx";
}

我们在变量 age 上加上注解 @Getter,并且加上了参数来设置访问级别,通过 onMethod_ 参数可以为我们在生成的 getAge 方法添加上其他注解,比如 @NonNull;在 name 上加上 @Getter 注解,并加上 lazy 参数并设为 true,表示开启懒加载。

接下来编译下,编译的 class 源代码如下:

package com.wupx.lombok;

import java.util.concurrent.atomic.AtomicReference;
import lombok.NonNull; public class GetterDemo {
private String age;
private final AtomicReference<Object> name = new AtomicReference(); public GetterDemo() {
} @NonNull
private String getAge() {
return this.age;
} public String getName() {
Object value = this.name.get();
if (value == null) {
synchronized(this.name) {
value = this.name.get();
if (value == null) {
String actualValue = "wupx";
value = "wupx" == null ? this.name : "wupx";
this.name.set(value);
}
}
} return (String)((String)(value == this.name ? null : value));
}
}

可以发现生成后的源代码文件中,getAge 方法访问修饰符为 private,并且方法上有一个 @NonNull 的注解;getName 方法没有刚开始就初始化一个字符串,而是只有调用该方法的时候判断该字段是否为空,若为空,则初始化一个字符串并返回,这样就可以为开销大的初始化操作做一个懒加载,只有当使用的时候才会主动加载这个字段。

其他的注解方法大家可以自己去实践操作下。

Lombok 优缺点

在了解完 Lombok 之后,让我们来分析下 Lombok 的优缺点吧!

Lombok 的优点有以下几点:

  • 通过注解自动生成样板代码,提高开发效率
  • 代码简洁,只关注相关属性
  • 新增属性后,无需刻意修改相关方法

但是 Lombok 也有一些缺点:

  • 降低了源代码的可读性和完整性
  • 加大对问题排查的难度(可能问题定位到不存在的行,无从下手)
  • 强 x 队友,因为需要 IDE 的相关插件的支持

总结

本文介绍了什么是 Lombok,Lombok 做了什么以及 Lombok 的实现原理,并且分析了 Lombok 的利弊,大家在享受到它的好处的同时,也应该考虑到它带来的一些问题,你在工作中有被队友强 x 吗?你对 Lombok 怎么看?欢迎留言谈论!

听说用 Lombok 可以早点下班?的更多相关文章

  1. 5 个 IDEA 必备插件,让效率成为习惯

    IDEA 是最好的 IDE,谁赞成,谁反对? IDEA 是 Java 开发人员中最受欢迎和用户友好的 IDE 之一,它具有许多便利的功能,例如智能代码完成,自动执行繁琐的重复开发任务,因此它已成为 J ...

  2. 分享Java开发的利器-Lombok

    译注:Lombok是一个很老的项目了,也非常实用,但奇怪的是这么多年来似乎一直不温不火.很多Lombok特性可以参考它的官网介绍哈.兄弟连教育在这里只是简单介绍一下它的基础功能. Lombok是一个旨 ...

  3. 2017年Android百大框架排行榜

    框架:提供一定能力的小段程序 >随意转载,标注作者"金诚"即可 >本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. >本文已经开源到Gith ...

  4. 2017年Android百大框架排行榜(转)

    一.榜单介绍 排行榜包括四大类: 单一框架:仅提供路由.网络层.UI层.通信层或其他单一功能的框架 混合开发框架:提供开发hybrid app.h5与webview结合能力.web app能力的框架 ...

  5. IT人为了自己父母和家庭,更得注意自己的身体和心理健康

    我前一阵在一家互联网公司,工作节奏是995,忙的时候,要晚上10点才能离开公司,有时候周六还得加班.自己感觉身体状况有所下降,且听说其它一个组,在体检后多少都查出问题来,细思极恐. 有时候确实忙,那么 ...

  6. 两个宝藏|关于我在github上冲浪时的一个小技巧。

    你好呀,我是歪歪. 前几天在 github 上冲浪的时候,发现了两个宝藏东西. 我也不藏着掖着了,拿出来给大家分享一下. 这两个宝藏是关于 arthas 和 SOFARegistry 的,这两个东西都 ...

  7. Go工程化 - 依赖注入

    我们在微服务框架kratos v2的默认项目模板中kratos-layout使用了google/wire进行依赖注入,也建议开发者在维护项目时使用该工具. wire 乍看起来比较违反直觉,导致很多同学 ...

  8. 一年之计在于春,2015开篇:PDF.NET SOD Ver 5.1完全开源

    前言: 自从我2014年下半年到现在的某电商公司工作后,工作太忙,一直没有写过一篇博客,甚至连14年股票市场的牛市都错过了,现在马上要过年了,而今天又是立春节气,如果再不动手,那么明年这个无春的年,也 ...

  9. 推荐 greenrobot eventbus,简化安卓开发,提高安卓维护性,优化安卓性能

    最近在研究移动开发,广泛的阅读有关cordova,apicloud,android资料.发现安卓的开发还是很简单的.再发现greenrobot eventbus开源框架不仅可以简化安卓开发,有可以大幅 ...

随机推荐

  1. 前沿理论、反思创新、产学结合——你不能错过的WSDM 2016大会

    第九届ACM网络搜索与数据挖掘国际会议(ACM International Conference on Web Search and Data Mining,简称WSDM)已于上周(2月22日-25日 ...

  2. c#或者C#.net中的“ToolTip”是“System.Windows.Forms.ToolTip”和“DevComponents.DotNetBar.ToolTip”之间的不明确的引用

    “ToolTip”是“System.Windows.Forms.ToolTip”和“DevComponents.DotNetBar.ToolTip”之间的不明确的引用 ,在编程时,有时候会编译出现不明 ...

  3. 攻防世界Mobile6 app1 XCTF详解

    XCTF_app1 先安装看看 点击芝麻开门之后会弹出“年轻人不要耍小聪明噢” 这大概就能看懂是点击之后进行判断,那就直接去看JEB,看看判断条件是什么 V1是输入的字符串,V2获取包信息(百度的), ...

  4. 前端每日实战:48# 视频演示如何用纯 CSS 创作一盘传统蚊香

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/BVpvMz 可交互视频教程 此视频 ...

  5. 超详细,多图文介绍redis集群方式并搭建redis伪集群

    超详细,多图文介绍redis集群方式并搭建redis伪集群 超多图文,对新手友好度极好.敲命令的过程中,难免会敲错,但为了截好一张合适的图,一旦出现一点问题,为了好的演示效果,就要从头开始敲.且看且珍 ...

  6. Nginx + uWSGI部署中的一些小坑

    1.invalid host in upstream报错 重新启动nginx : sudo /etc/init.d/nginx restart 原因是在配置负载均衡nginx.conf配置文件时,发现 ...

  7. Deepin环境下启动Pycharm没有启动图标解决办法

    小伙伴们在deepin下运行pycharm时,是不是需要通过sh文件启动? 下面告诉大家如何将pycharm图标放在桌面上: 1.在桌面打开终端,输入命令: sudo gedit /usr/share ...

  8. 【译文连载】 理解Istio服务网格(第七章 安全)

    全书目录 第一章 概述 第二章 安装 第三章 流控 第四章 服务弹性 第五章 混沌测试 第六章 可观测性 本文目录 第7章 安全 7.1 身份认证 7.1.1 Kubernetes上的Istio的身份 ...

  9. 大型Java进阶专题(三) 软件架构设计原则(下)

    前言 ​ 今天开始我们专题的第二课了,本章节继续分享软件架构设计原则的下篇,将介绍:接口隔离原则.迪米特原则.里氏替换原则和合成复用原则.本章节参考资料书籍<Spring 5核心原理>中的 ...

  10. docker的安装使用

    目录 Docker 入门到精通 CentOS安装Docker 设置管理Docker的仓库 安装Docker Engine-Community Docker基础命令 开启关闭 镜像操作 容器操作 Doc ...