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

公司发表声明!禁止所有程序员使用Lombok!然后用性能直接打C!

时间:2023-03-16 18:57:32 科技观察

前言在我春节上班几天后,公司发布声明,禁止所有程序员在新项目中使用Lombok。为什么?这个很难(硬!不得不承认,Lombok是一个非常优秀的Java库,它可以让你在写更少的代码的同时玩得爽。几个简单的注释可以杀死大量的模板代码。但是,所有的源码都是用来阅读很多时间的,只有很少的时间用来执行(这句话大家可以仔细看)。接下来,我将用几个熟悉的场景来重现我们是如何落入龙目岛的诡计陷阱的。爱的开始,恨的起源面对Lombok提供的众多“神位”,你不介意给IDE加个新插件。IntelliJIDEA玩家只需搜索“LombokPlugin”即可找到此神器并安装。爱上Lombok从安装Lombok插件开始,恨之入骨。没有使用Lombok之前,我们的源代码看起来是这样的:publicclassMyObject{privateLongid;私有字符串名称;私人年龄;私人诠释性别;publicLonggetId(){返回id;}publicvoidsetId(Longid){this.id=id;}publicStringgetName(){返回名称;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){返回年龄;}publicvoidsetAge(intage){this.age=age;}publicintgetGender(){返回性别;}publicvoidsetGender(intgender){this.gender=gender;}@Overridepublicbooleanequals(Objecto){if(this==o){返回真;}if(o==null||getClass()!=o.getClass()){返回假;}MyObjectobj=(MyObject)o;返回年龄=obj.age&&gender=obj.gender&&Objects.equals(id,obj.id)&&Objects.queals(名称,obj.name);}@OverridepublicinthashCode(){returnObjects.hash(id,name,age,gender);}@OverridepublicStringtoString(){return"MyObject{"+"id="+id+"name="+name+"age="+age+"gender="+gander+"}";}}每个JavaBean都会填充上面的getter,setter,equals,hashCode,toString等模板代码,这看起来像个胖子(不得不承认Java是一门有缺陷的编程语言)当我们安装Lombok插件时,IDE可以识别它的炫酷注解。使用Lombok的@Getter和@Setter注解后,代码看起来会很苗条,如下所示:@Getter@SetterpublicclassMyObject{privateLongid;私有字符串名称;私人年龄;私人诠释性别;@Overridepublicbooleanequals(Objecto){if(this==o){返回真;}if(o==null||getClass()!=o.getClass()){返回false;}MyObjectobj=(MyObject)o;returnage=obj.age&&gender=obj.gender&&Objects.equals(id,obj.id)&&Objects.queals(name,obj.name);}@OverridepublicinthashCode(){returnObjects.hash(id,name,age,gender);}@OverridepublicStringtoString(){return"MyObject{"+"id="+id+"name="+name+"age="+age+"gender="+gander+"}";}}代码现在看起来更好了吗?但这不是最好的时机。现在其他方法已被替换,让我们也删除toString方法。如你所愿,你可以使用@ToString注解去掉对应的方法:@Getter@Setter@EqualsAndHashCodepublicclassMyObject{privateLongid;私有字符串名称;私人年龄;私人诠释性别;@OverridepublicStringtoString(){return"MyObject{"+"id="+id+"name="+name+"age="+age+"gender="+gander+"}";}}经过Lombok的绝招,是不是又酷又瘦又性感呢?你以为就这样结束了吗?远不止于此。你会发现类名上一大堆注解看起来很别扭。Lombok提供了一个组合注解@Data,可以代替类名头上的那个疙瘩:@DatapublicclassMyObject{privateLongid;私有字符串名称;私人年龄;privateintgender;}现在,Lombok是否使您的伴侣成为您认为的完美对象?魔王之“体”清冷脱俗。Lombok还有一些其他的注解,比如@Slf4j、@NoArgsConstructor、@AllArgsConstructor等,Lombok的用法介绍不是本文的重点。上面代码行数的变化过程,可能是无数程序员爱上Lombok的主要原因。就像一个肥胖的人逐渐变成一个苗条的人。同时也让你看到一个现象:你觉得程序员懒惰吗?其他时候他们比你想象的更懒惰。虽然很酷,但它也为代码种下了诅咒。扭曲的审美,爱情隐患扭曲的审美导致被检查对象处于亚健康状态。使用Lombok插件后,我们的代码也处于“亚健康”状态。回到最开始的那句话:所有的源代码,大量的时间是用来阅读的,只有少量的时间是用来执行的。本质上,我们都在寻求减少程序中的样板代码,使其代码更加简洁明了,从而提高代码的可读性和可维护性。但是龙目岛并没有实现我们追求的愿景。它只是利用了Java语言在编译期的空隙期,用一种非常刁钻的方式,将我们需要的方法注入(写入)到当前类中。在中,这个过程很像破解我们的代码,只是一个看起来很酷的技巧。这种trick并不聪明也不安全,反而会破坏Java代码已有的特性和代码的可读性。下面结合自己使用Lombok后的感受,谈谈Lombok带来的几大痛点。1.JDK版本问题当我想将现有项目的JDK从Java8升级到Java11时,发现Lombok无法正常运行。所以只好把项目源码中所有的Lombok注解全部去掉,使用IDE自带的函数生成getter/setter、equals、hashCode、toString、constructor方法。您还可以使用Delombok工具来完成此过程。但这毕竟会消耗你大量的时间。2.强制使用当你在源代码中使用了Lombok,而你的代码刚好被其他人使用,那么依赖你代码的人也必须安装Lombok插件(不管他们喜不喜欢),并且在同时花时间了解Lombok注解的使用,如果不这样做,代码将无法正常运行。在使用了Lombok之后,我发现这是一个非常流氓的行为。3、可读性差Lombok隐藏了JavaBean封装的细节。如果使用@AllArgsConstructor注解,它会提供一个巨大的构造函数,让外界有机会在对象初始化时修改类中的所有属性。首先,这是极不安全的,因为我们不想修改类中的某些属性;另外,如果一个类中有几十个属性,就会有一个包含几十个参数的构造函数被删除。Lombok注入类,属于非理性行为;其次,构造函数参数的顺序完全由Lombok控制,我们无法控制,只有当你需要调试的时候,你才发现有一个奇怪的“小强”在等着你;最后,在运行代码之前,所有的JavaBean中的方法你只能想象它们的样子,你是看不到的。4.增加代码耦合当你使用Lombok编写某个模块的代码时,其他依赖该模块的代码需要引入Lombok依赖,同时你还需要在IDE中安装Lombok插件。Lombok的依赖包虽然不大,但是因为其中一个使用了Lombok,其他所有的依赖都要强制加入Lombok的Jar包。这是一种侵入式耦合。如果再出现JDK版本问题,那就惨了。5.得不偿失使用Lombok,一时觉得很爽,但是污染了你的代码,破坏了Java代码的完整性、可读性和安全性,同时增加了团队的技术债。得不偿失。如果你真的想让你的代码更简洁,同时兼顾可读性和编码效率,你还不如使用主流的Scala或Kotlin这种基于JVM的语言。总结Lombok本身就是一个优秀的Java代码库。它使用一种巧妙的语法糖来简化Java编码,并提供一种简化Java代码的方法。但是,在使用这个代码库的时候,需要了解Lombok并不是一个标准的Java库。使用Lombok会增加团队的技术债,降低代码的可读性,增加代码的耦合和调试难度。Lombok虽然在一定程度上减少了样板代码的编写,但也带来了一些未知的风险。如果你参与的是团队项目(或大型项目),请与你的团队沟通,考虑到后续的升级和扩展,再三考虑是否使用Lombok。