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

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

服务器之家 - 编程语言 - Java教程 - 为什么有的团队严禁使用Lombok?

为什么有的团队严禁使用Lombok?

2021-09-29 23:26Java极客技术鸭血粉丝Tang Java教程

Java,作为一款非常热门的编程语言,尽管它有着非常丰富的语言特性,完全面向对象编程,编程高度规范化。

为什么有的团队严禁使用Lombok?

一、介绍

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

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

为什么有的团队严禁使用Lombok?

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

二、Lombok

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

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

为什么有的团队严禁使用Lombok?

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

  1. org.projectlombok
  2. lombok
  3. 1.18.12
  4. provided

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

  1. importlombok.Data;
  2. @Data
  3. publicclassUser{
  4. privateStringid;
  5. privateStringage;
  6. privateStringname;
  7. //可以不用显式写get、set方法
  8. }

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

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

  1. publicclassUser{
  2. privateStringid;
  3. privateStringage;
  4. privateStringname;
  5. publicUser(){
  6. }
  7. publicStringgetId(){
  8. returnthis.id;
  9. }
  10. publicStringgetAge(){
  11. returnthis.age;
  12. }
  13. publicStringgetName(){
  14. returnthis.name;
  15. }
  16. publicvoidsetId(Stringid){
  17. this.id=id;
  18. }
  19. publicvoidsetAge(Stringage){
  20. this.age=age;
  21. }
  22. publicvoidsetName(Stringname){
  23. this.name=name;
  24. }
  25. publicbooleanequals(Objecto){
  26. if(o==this){
  27. returntrue;
  28. }elseif(!(oinstanceofUser)){
  29. returnfalse;
  30. }else{
  31. Userother=(User)o;
  32. if(!other.canEqual(this)){
  33. returnfalse;
  34. }else{
  35. label47:{
  36. Objectthis$id=this.getId();
  37. Objectother$id=other.getId();
  38. if(this$id==null){
  39. if(other$id==null){
  40. breaklabel47;
  41. }
  42. }elseif(this$id.equals(other$id)){
  43. breaklabel47;
  44. }
  45. returnfalse;
  46. }
  47. Objectthis$age=this.getAge();
  48. Objectother$age=other.getAge();
  49. if(this$age==null){
  50. if(other$age!=null){
  51. returnfalse;
  52. }
  53. }elseif(!this$age.equals(other$age)){
  54. returnfalse;
  55. }
  56. Objectthis$name=this.getName();
  57. Objectother$name=other.getName();
  58. if(this$name==null){
  59. if(other$name!=null){
  60. returnfalse;
  61. }
  62. }elseif(!this$name.equals(other$name)){
  63. returnfalse;
  64. }
  65. returntrue;
  66. }
  67. }
  68. }
  69. protectedbooleancanEqual(Objectother){
  70. returnotherinstanceofUser;
  71. }
  72. publicinthashCode(){
  73. intPRIME=true;
  74. intresult=1;
  75. Object$id=this.getId();
  76. intresult=result*59+($id==null?43:$id.hashCode());
  77. Object$age=this.getAge();
  78. result=result*59+($age==null?43:$age.hashCode());
  79. Object$name=this.getName();
  80. result=result*59+($name==null?43:$name.hashCode());
  81. returnresult;
  82. }
  83. publicStringtoString(){
  84. return"User(id="+this.getId()+",age="+this.getAge()+",name="+this.getName()+")";
  85. }
  86. }

很清晰的看到,使用@Data注解之后,User类新增了get、set、hashCode、equals和toString方法。

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

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

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

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

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

三、有哪些坏处呢?

3.1、强迫队友也安装 Lombok

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

3.2、代码可调试性降低

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

Lombok虽然给我们节省了get和set方法的编程,但是如果我想知道类的某个属性被哪些方法操作给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被完全暴露在外界了。

  1. publicclassUser{
  2. privateStringid;
  3. privateStringage;
  4. privateStringname;
  5. privateStringtag="学生";
  6. publicStringgetTag(){
  7. returntag;
  8. }
  9. }

3.5、影响 jdk 升级

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

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

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

四、总结

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

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

因此大家在评估要不要在代码中引入Lombok的时候,在想它的优点同时,能够考虑到它会带来的哪些问题,以便更好的做决定!

五、参考

https://projectlombok.org/

https://time.geekbang.org/column/article/164907

http://blog.itpub.net/69908877/viewspace-2676272/

原文链接:https://mp.weixin.qq.com/s/5EE0Vf8A2-8fnMQGfw0U-w

延伸 · 阅读

精彩推荐
  • Java教程Java中Object.equals和String.equals的区别详解

    Java中Object.equals和String.equals的区别详解

    这篇文章主要给大家介绍了Java中Object.equals和String.equals的区别,文中通过一个小示例让大家轻松的明白这两者的区别,对大家具有一定的参考价值,需要的...

    Wing5322020-09-19
  • Java教程Java源码解析TreeMap简介

    Java源码解析TreeMap简介

    今天小编就为大家分享一篇关于Java源码解析TreeMap简介,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    李灿辉7852021-06-29
  • Java教程详解mybatis #{}和${}的区别、传参、基本语法

    详解mybatis #{}和${}的区别、传参、基本语法

    这篇文章主要介绍了mybatis #{}和${}的区别、传参、基本语法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参...

    wutongyuWxc2112020-07-22
  • Java教程一名Java高级工程师需要学什么?

    一名Java高级工程师需要学什么?

    作为一名Java高级工程师需要学什么?如何成为一名合格的工程师,这篇文章给了你较为详细的答案,需要的朋友可以参考下...

    工程师-搁浅2532020-12-17
  • Java教程Java截取中英文混合字符串的方法

    Java截取中英文混合字符串的方法

    这篇文章主要为大家详细介绍了Java截取中英文混合字符串的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    余-雷4152019-06-30
  • Java教程手把手教你写一个spring IOC容器的方法

    手把手教你写一个spring IOC容器的方法

    这篇文章主要介绍了手把手教你写一个spring IOC容器的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参...

    华为云8472021-09-04
  • Java教程Java对List进行排序的两种实现方法

    Java对List进行排序的两种实现方法

    这篇文章主要给大家介绍了关于Java对List进行排序的两种实现方法,第一种是实体类自己实现比较,第二种是借助比较器进行排序,下面开一起看看详细的...

    shangmingchao4442020-07-16
  • Java教程Spring Boot与Spark、Cassandra系统集成开发示例

    Spring Boot与Spark、Cassandra系统集成开发示例

    本文演示以Spark作为分析引擎,Cassandra作为数据存储,而使用Spring Boot来开发驱动程序的示例。对spring boot 与spark cassandra集成开发示例代码感兴趣的朋友跟着脚...

    汪云飞11402021-03-29