Java 中的 Lombok 到底能不能用?

一、摘要

Java,作为一款非常热门的编程语言,尽管它有着非常丰富的语言特性,完全面向对象编程,编程高度规范化,但是也有一个最受大家诟病的一个缺点:啰嗦,尤其是当你开发了很多年之后,你会明显的感受到,相比动态语言,java 定义变量之前,要先创建类,然后定义变量类型,每个类要写很多的get/set/toString/hashCode/equals等等方法。

尤其是当一个实体类,高达几十个变量时,写完get、set方法之后,一个实体类的长度快接近一千行。

2bcbd3f700fec6c12f0f277f316624a2.jpeg

为了避免写这些“罗嗦”的方法,很多程序员一直在寻觅着找一个能够使他们摆脱这种重复劳动工作的工具,例如:idea、eclipse 开发工具的快捷生成get、set方法的工具,还有我们今天要谈论的这个Lombok工具。

二、Lombok

Lombok 是一款非常流行的代码简洁工具,利用它的注解特性,直接就可以帮我们省去高大几百行的get、set方法,操作非常方便。

如果是idea开发工具,可以直接在preferences -> plugins里面搜索lombok,然后点击安装即可!

f03492874c244019e3c649acf3b78cca.jpeg

接着,在项目工程中导入lombok依赖包!

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

最后,只需要在对应的实体类上加上@Data注解,即可完成类属性get/set的注入。

import lombok.Data;@Data
public class User {private String id;private String age;private String name;//可以不用显式写get、set方法
}

使用@Data注解在类上,这个实体类中的属性就不需要显式写getset方法了。

对这个类进行编译之后,我们打开User.class文件,看看编译后的文件内容长啥样?

public class User {private String id;private String age;private String name;public User() {}public String getId() {return this.id;}public String getAge() {return this.age;}public String getName() {return this.name;}public void setId(String id) {this.id = id;}public void setAge(String age) {this.age = age;}public void setName(String name) {this.name = name;}public boolean equals(Object o) {if (o == this) {return true;} else if (!(o instanceof User)) {return false;} else {User other = (User)o;if (!other.canEqual(this)) {return false;} else {label47: {Object this$id = this.getId();Object other$id = other.getId();if (this$id == null) {if (other$id == null) {break label47;}} else if (this$id.equals(other$id)) {break label47;}return false;}Object this$age = this.getAge();Object other$age = other.getAge();if (this$age == null) {if (other$age != null) {return false;}} else if (!this$age.equals(other$age)) {return false;}Object this$name = this.getName();Object other$name = other.getName();if (this$name == null) {if (other$name != null) {return false;}} else if (!this$name.equals(other$name)) {return false;}return true;}}}protected boolean canEqual(Object other) {return other instanceof User;}public int hashCode() {int PRIME = true;int result = 1;Object $id = this.getId();int result = result * 59 + ($id == null ? 43 : $id.hashCode());Object $age = this.getAge();result = result * 59 + ($age == null ? 43 : $age.hashCode());Object $name = this.getName();result = result * 59 + ($name == null ? 43 : $name.hashCode());return result;}public String toString() {return "User(id=" + this.getId() + ", age=" + this.getAge() + ", name=" + this.getName() + ")";}
}

很清晰的看到,使用@Data注解之后,User类新增了getsethashCodeequalstoString方法。

通过上面的例子,大家可以发现,使用@Data注解可以大大减少了代码量,使代码非常简洁,这也是很多开发者热衷于使用Lombok的主要原因。

Lombok的工作原理是怎么实现的呢

由于Java的官方版本没有提供这种快速生成方法的注解工具,类似Lombok这样的工具,其实都是使用了从Java 6JSR 269Annotation Processing技术中实现方法的注入。

简单的说,就是使用了 Java 非公开的 API,在 javac 编译代码时,通过强类型转换获取JavacAnnotationProcessor对象,再从JavacAnnotationProcessor的方法里面拿到抽象语法树(AST)做强制修改,注入get、set等方法。

使用Lombok这种方案,有个最大的好处,就是可以节省大量的重复代码,让代码更佳简洁!但是也有很多弊端!

三、有哪些坏处呢?

3.1、强迫队友也安装 Lombok

当你在使用Lombok工具插件来快速开发项目的时候,如果别的同事也要和你一起协作开发项目,那么他不得不也要安装Lombok插件,不然项目编译会报错。

3.2、代码可调试性降低

代码可调试性会降低,为什么会这么说呢?

Lombok虽然给我们节省了getset方法的编程,但是如果我想知道类的某个属性被哪些方法操作给set了,如果用原生的方法,可以很好的知道调用方。但是如果使用Lombok插件来生成,这个时候你根本无从得知。甚至没办法调试!

3.3、不懂 Lombok 注解,会踩坑

我们知道,使用@Data会重写hashCode()equals()方法,如果是单个实体类,没有继承的话,你使用@Data不会产生问题。

但是如果这个实体类又继承了父类,@Data只会重写子类的hashCode()equals()方法,不会把父类的属性加进去,这样就会导致,例如当你在使用HashMap的时候,用当前这个实体类作为key,可能会得到意想不到的结果。

遇到这种情况,你可以在类上加上这个注解@EqualsAndHashCode(callSuper=true),子类的hashCode()equals()方法会加入父类的属性。

3.4、破坏封装性

封装是 java 面向对象编程中非常重要的一个特性。

例如,针对User实体类,我新家一个tag属性,我只想暴露它的get方法,不想暴露set方法给外部,没有用@Data注解的时候,我可以很灵活的进行编程,但是使用@Data注解之后,属性tag被完全暴露在外界了。

public class User {private String id;private String age;private String name;private String tag = "学生";public String getTag() {return tag;}}

3.5、影响 jdk 升级

其实以上的坑点,都不算什么很大的坑点,在我看来,最大的坑点其实就是Lombok的工作原理,使用了非官方支持的 API 接口通过程序强制植入方式来修改类,实现getset等方法的注入

按照如今 JDK 的升级频率,每半年都会推出一个新的版本,但是Lombok作为一个第三方工具,并且是由开源团队维护的,那么他的迭代速度是无法保证的。

假如某天JDK把这种后门堵住了,那Lombok基本上就不能用了,到时候又是个麻烦事情。

四、总结

Lombok 作为一款非常流行的工具插件,肯定有它自身的优势所在,到底建不建议在日常开发中使用,我个人其实是一个中立的态度,如果你们团队的人都喜欢它,那推荐你使用,在使用之前,最好培训一下,有哪些坑点,避免踩坑。

如果多数人不太喜欢用它,那就不推荐你使用,很多公司禁止你使用它的原因,其实这种插件有点类似那种流氓插件,工作原理不是官方所认可的方式来实现,假如某天新版本的 jdk 突然把这个漏洞给堵住了,那么项目想要升级 jdk,就比较困难。

因此大家在评估要不要在代码中引入Lombok的时候,在想它的优点同时,能够考虑到它会带来的哪些问题,那么本文的目的也就达到了!

五、参考

1、projectlombok

2、geekbang - lombok

3、itpub - lombok

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543973.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

旅行商问题

旅行商问题 (Travelling Salesman problem) This problem can be stated as- "Given n number of cities and a travelling salesman has to visit each city. Then we have to find the shortest tour so that the travelling salesman can visit each and every city on…

分页 + 模糊查询竟然有坑?

不知道你有没有使用过Mysql的like语句&#xff0c;进行模糊查询&#xff1f;不知道你有没有将查询结果&#xff0c;进行分页处理&#xff1f;模糊查询&#xff0c;加上分页处理&#xff0c;会有意想不到的坑&#xff0c;不信我们继续往下看。我之前提供过一个品牌查询接口&…

导致事务@Transactional失效的5种场景!

作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;一个程序中不可能没有事务&#xff0c;而 Spring 中&#xff0c;事务的实现方式分为两种&#xff1a;编程式事务和声…

操作系统 cpu调度_CPU调度| 操作系统

操作系统 cpu调度调度标准 (Scheduling Criteria) There are many criteria which have been suggested for comparing the CPU scheduling algorithms. The characteristics which are used for comparison and then used to determine the best algorithms, for this some of…

IOS中KVO模式的解析与应用

最近老翁在项目中多处用到了KVO&#xff0c;深感这种模式的好处。现总结如下&#xff1a; 一、概述 KVO,即&#xff1a;Key-Value Observing&#xff0c;它提供一种机制&#xff0c;当指定的对象的属性被修改后&#xff0c;则对象就会接受到通知。简单的说就是每次指定的被观察…

使用 lambda 实现超强的排序功能

我们在系统开发过程中&#xff0c;对数据排序是很常见的场景。一般来说&#xff0c;我们可以采用两种方式&#xff1a;借助存储系统&#xff08;SQL、NoSQL、NewSQL 都支持&#xff09;的排序功能&#xff0c;查询的结果即是排好序的结果查询结果为无序数据&#xff0c;在内存中…

java 的23种设计模式 之单身狗和隔壁老王的故事

2019独角兽企业重金招聘Python工程师标准>>> 觉得代码写的别扭了&#xff0c;回头翻翻java 的23种设计模式。today,额,这么晚了&#xff0c;困了。就弄个最简单的单例模式吧。单例模式&#xff1a;俗称单身狗 package singleton; public class SingleTon { private …

使用python学线性代数_二项式过程| 使用Python的线性代数

使用python学线性代数When we flip a coin, there are two possible outcomes as head or tail. Each outcome has a fixed probability of occurrence. In the case of fair coins, heads and tails each have the same probability of 1/2. In addition, there are cases in …

工作中常见的 6 种设计模式,你用过几种?

前言 哈喽&#xff0c;大家好。平时我们写代码呢&#xff0c;多数情况都是流水线式写代码&#xff0c;基本就可以实现业务逻辑了。如何在写代码中找到乐趣呢&#xff0c;我觉得&#xff0c;最好的方式就是&#xff1a;使用设计模式优化自己的业务代码。今天跟大家聊聊日常工作中…

这12款idea插件,能让你代码飞起来!

前言基本上每个程序员都会写代码&#xff0c;但写代码的速度不尽相同。为什么有些人&#xff0c;一天只能写几百行代码&#xff1f;而有些人&#xff0c;一天可以写几千行代码&#xff1f;有没有办法&#xff0c;可以提升开发效率&#xff0c;在相同的时间内&#xff0c;写出更…

node js 开发网站_使用Node JS开发网站

node js 开发网站You will have your own fully functional website running on "localhost" after going through this article. 阅读完本文后&#xff0c;您将在“ localhost”上运行自己的功能齐全的网站 。 Basic knowledge of JavaScript and HTML is a prereq…

Java:LocalDate / LocalDateTime加减时间

在线API参考&#xff1a;LocalTime (Java Platform SE 8 ) 方法介绍 方法1方法1说明plusYears(long years) minusYears(long years) 返回增加/减少了年数的副本plusMonths(long months) minusMonths(long months)返回增加/减少了月数的副本plusWeeks(long weeks) minusWeeks(…

集合 List 分片的 5 种实现

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;前些天在实现 MyBatis 批量插入时遇到了一个问题&#xff0c;当批量插入的数据量比较大时&#xff0c;会导致程序执行报错&a…

使用它给 ​xxl-job 添加任务,太爽了

xxl-job是一款非常优秀的任务调度中间件&#xff0c;轻量级、使用简单、支持分布式等优点&#xff0c;让它广泛应用在我们的项目中&#xff0c;解决了不少定时任务的调度问题。我们都知道&#xff0c;在使用过程中需要先到xxl-job的任务调度中心页面上&#xff0c;配置执行器ex…

dubboSPI机制浅谈

2019独角兽企业重金招聘Python工程师标准>>> &#xfeff;&#xfeff;&#xfeff;本文重点讲述SPI机制&#xff0c;从jdk和dubbo 1、jdk spi机制 2、dubbo spi实现 首先spi是什么&#xff1f; SPI是为某个接口寻找服务实现的机制。为了实现在模块装配的时候能不在…

彻底搞懂 SpringBoot 中的 starter 机制

前言我们都知道&#xff0c;Spring的功能非常强大&#xff0c;但也有些弊端。比如&#xff1a;我们需要手动去配置大量的参数&#xff0c;没有默认值&#xff0c;需要我们管理大量的jar包和它们的依赖。为了提升Spring项目的开发效率&#xff0c;简化一些配置&#xff0c;Sprin…

Java 中验证时间格式的 4 种方法

大家好&#xff0c;今天咱们来讲一下&#xff0c;Java 中如何检查一个字符串是否是合法的日期格式&#xff1f;为什么要检查时间格式&#xff1f;后端接口在接收数据的时候&#xff0c;都需要进行检查。检查全部通过后&#xff0c;才能够执行业务逻辑。对于时间格式&#xff0c…

Redis 实现分布式锁的 7 种方案

前言日常开发中&#xff0c;秒杀下单、抢红包等等业务场景&#xff0c;都需要用到分布式锁。而Redis非常适合作为分布式锁使用。本文将分七个方案展开&#xff0c;跟大家探讨Redis分布式锁的正确使用方式。如果有不正确的地方&#xff0c;欢迎大家指出哈&#xff0c;一起学习一…

css复选框样式_使用CSS样式复选框

css复选框样式Introduction: 介绍&#xff1a; Sometimes we want to develop a website or web page that would contain a form and through that form, we want to get some information from the user. Now that information could be of any type depending on the kind …