当前位置: 首页 > 科技观察

项目中应该使用Lombok吗?

时间:2023-03-20 14:04:03 科技观察

Java,作为一门非常流行的编程语言,虽然它有非常丰富的语言特性,完全面向对象的编程,高度标准化的编程,但是它也有一个最被大家诟病的缺点:啰嗦,尤其是当你开发多年后,你会明显感觉到,与动态语言相比,在java中定义变量之前,必须先创建一个类,然后定义变量类型。每个类都需要写很多get/set/toString/hashCode/equals等方法。尤其是一个实体类有几十个变量的时候,写完get和set方法,一个实体类的长度差不多有上千行。为了避免写出这些“罗嗦”的方法,很多程序员一直在寻找一种工具可以让自己从这种重复性的工作中解脱出来,比如:idea,eclipse快速生成get和set方法的开发工具,还有就是这个今天要说的Lombok工具。1.LombokLombok是一款非常流行的代码简洁工具。利用它的注解特性,可以直接省去我们几百行的get、set方法,操作非常方便。如果是idea开发工具,可以直接在preferences->plugins中搜索lombok,然后点击安装!接下来在项目工程中导入lombok依赖包!org.projectlomboklombok1.18.12provided最后只在对应的添加@Data注解给实体类完成类属性get/set的注入。importlombok.Data;@DatapublicclassUser{privateStringid;私有字符串年龄;私有字符串名称;//不需要显式写get和set方法}在类上使用@Data注解,这个实体类中的属性就不需要显式写get和set方法了。编译完这个类,我们打开User.class文件,看看编译后的文件内容是什么样的?公共类用户{私有字符串id;私有字符串年龄;私有字符串名称;publicUser(){}publicStringgetId(){returnthis.id;}publicStringgetAge(){returnthis.age;}publicStringgetName(){returnthis.name;}publicvoidsetId(Stringid){this.id=id;}publicvoidsetAge(Stringage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}publicbooleanequals(Objecto){if(o==this){returntrue;}elseif(!(oinstanceofUser)){returnfalse;}else{用户other=(User)o;如果(!other.canEqual(this)){返回false;}else{label47:{对象this$id=this.getId();对象other$id=other.getId();如果(吨his$id==null){if(other$id==null){breaklabel47;}}elseif(this$id.equals(other$id)){breaklabel47;}返回假;对象this$age=this.getAge();对象other$age=other.getAge();如果(this$age==null){如果(other$age!=null){returnfalse;}}elseif(!this$age.equals(other$age)){返回假;}对象this$name=this.getName();对象other$name=other.getName();if(this$name==null){if(other$name!=null){返回假;}}elseif(!this$name.equals(other$name)){返回假;}返回真;}}}protectedbooleancanEqual(Objectother){returnotherinstanceofUser;}publicinthashCode(){intPRIME=true;整数结果=1;对象$id=this.getId();intresult=result*59+($id==null?43:$id.hashCode());对象$age=this.获取年龄();结果=结果*59+($age==null?43:$age.hashCode());对象$name=this.getName();结果=结果*59+($name==null?43:$name.hashCode());返回结果;}publicStringtoString(){return"User(id="+this.getId()+",age="+this.getAge()+",name="+this.getName()+")";}}显然,User类在使用了@Data注解后,增加了get、set、hashCode、equals、toString方法。通过上面的例子可以发现,使用@Data注解可以大大减少代码量,让代码变得非常简洁,这也是开发很多。开发者热衷于使用Lombok的主要原因。龙目岛如何运作?由于Java正式版并没有提供这种快速生成方法的注解工具,所以像Lombok这样的工具实际上是利用了Java6和JSR269的AnnotationProcessing技术来实现方法注入。简单的说,就是使用Java的非公开API。javac编译代码时,通过强类型转换得到JavacAnnotationProcessor对象,然后从JavacAnnotationProcessor方法中得到抽象语法树(AST)进行强制修改,注入get、set等方法。使用Lombok最大的好处就是可以省去很多重复的代码,让代码更加简洁!但是也有很多缺点!3、缺点是什么?3.1.强制队友也安装Lombok当你使用Lombok工具插件快速开发项目时,如果其他同事要与你协作开发项目,那么他必须安装Lombok插件,否则项目编译会报错。3.2.Decreasedcodedebuggability代码的可调试性会降低,为什么这么说呢?Lombok虽然省去了我们get和set方法的编程,但是如果我想知道是哪个方法设置了类的某个属性,如果使用native方法,就可以很好的知道调用者。但是如果你是用Lombok插件生成的,此时你是无从知晓的。甚至无法调试!3.3.不懂Lombok注解,就踩坑了。我们知道使用@Data会重写hashCode()和equals()方法。如果是没有继承的单实体类,使用@Data不会有问题。但是如果这个实体类继承了父类,那么@Data只会重写子类的hashCode()和equals()方法,不会添加父类的属性,这样就会造成,比如当你在使用HashMap使用当前实体类作为键时,可能会得到意想不到的结果。这种情况下,可以给类加上这个注解@EqualsAndHashCode(callSuper=true),子类的hashCode()和equals()方法会加上父类的属性。3.4.打破封装封装是java面向对象编程中一个非常重要的特性。例如,对于User实体类,我有一个新的标记属性。我只想暴露它的get方法,不想对外暴露set方法。当我不使用@Data注解时,可以灵活编程,但是使用@Data注解后,属性标签就完全暴露在外界了。公共类用户{私有字符串id;私有字符串年龄;私有字符串名称;私人字符串标签=“学生”;publicStringgetTag(){返回标签;在我看来,最大的坑其实是Lombok的工作原理,使用非官方支持的API接口,通过程序强制植入修改类,实现get、set等方法的注入。按照目前JDK的升级频率,每六个月就会发布一个新版本,但作为第三方工具,Lombok由开源团队维护,迭代速度无法保证。如果哪天JDK把这种后门给堵了,那Lombok基本就不能用了,到时候就是一件麻烦的事情。4.总结作为一款非常流行的工具插件,Lombok一定有自己的优势。日常开发中是否推荐使用,我个人持中立态度。如果你团队中的每个人都喜欢它,那么建议你使用它。在使用之前,最好训练一下有哪些陷阱,以免踩坑。如果大多数人不喜欢使用它,那么不建议您使用它。许多公司禁止您使用它。其实这种外挂有点类似于那种流氓外挂。工作原理并未以官方认可的方式实施。如果有一天新版本的jdk突然堵住了这个漏洞,那么项目升级jdk就比较困难了。因此,大家在评估是否在代码中引入Lombok时,既要考虑它的优点,又要考虑它会带来的问题,那么本文的目的就达到了!5.参考1、projectlombok2、geekbang-lombok3、itpub-lombok