新来的同事不会用 Lombok,因此会引起本文!java
最近公司新来一个高 Java 的同事,搞了半天项目尚未跑起来,后来叫我过去帮他看一下,而后指着红色的编译错误和我说是否是代码有问题。。ide
我顿时就心想,这人是否是太水了啊,工做三年了,简单的编译问题都搞不定?可是当我认真看了错误以后,发现……他居然没装 Lombok 插件……工具
而后我和他说出了问题所在,让他安装下 Lombok 插件再从新编译下,他竟然和我说不知道什么插件,感受他没用过吧,甚至都没有据说过。学习
好吧,我认了,我默默亲自为他把 Lombok 装上了!ui
若是你没用过,我也不以为奇怪,Lombok 毕竟是团队工具,但若是你也没听过,那就感受获取新知识自我提高学习的能力有点弱了。this
固然,本篇不是教你怎么用 Lombok,由于我以前就已经写过教程分享过了,不会的能够点击这个连接看下,还热乎着呢。spa
由于,最近也有看到一些公众号在发放弃 Lombok 的文章,再结合最近一个新同事的状况,也谈谈到底要不要用 Lombok。插件
一味地让你们放弃,我感受有点偏激了,任何事物,存在就即合理,关键是利弊权衡的问题罢了。设计
用不用 Lombok,又是分两派,公说公有理,婆说婆有理,仁者见仁,智者见智,谁也说服不了谁,相似 Eclipse 和 IntelliJ IDEA 谁更好用之争!3d
我想说,争这些没任何意义,这彻底取决于团队的决策,取决于你的团队能不能 Hold 住这个东西,若是利 > 弊,用它就对了,若是弊 > 利,那就考虑放弃吧。
若是你是我的项目,请大胆用吧!
Lombok 的好处就不说了,就是帮咱们大量简化代码,这里重点说下为何有人不推荐使用 Lombok。
使用 Lombok 须要两个必要的组件:
1)Lombok 依赖包
使用 Lombok 的注解,就必须引用它的依赖,最后编译成最终的 class 类,如 Maven 依赖示例:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
这个不会引发问题,由于它是代码的一部分,并且在项目一开始的时候就引入进去了。
2)Lombok IDE 插件
Eclipse/ IntelliJ IDEA 都提供了 Lombok 插件,用来识别 Lombok 的注解,不然会显示编译报错。
IntelliJ IDEA 插件示例:
若是某一我的为了方便本身而使用,其余人不肯意使用或者被迫使用,将致使团队其余成员代码无法正常编译,这也是问题的关键所在。
还有就是文章以前说的,来了一个新同事,若是他没有相应的使用经验,就须要额外的指导,对于老员工来讲无疑也是一个额外的工做量。
@Data 注解用在类上,等同于下面这几个注解合集:
@Getter
@Setter
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode
@Getter, @Setter, @ToString 很简单,用起来也没问题,而 @RequiredArgsConstructor和 @EqualsAndHashCode 须要注意下。
1)RequiredArgsConstructor
Generates a constructor with required arguments.Required arguments are final fields and fields with constraints such as {@code @NonNull}.
即生成一个类构造器,参数包含全部用 final 修饰、以及 @NonNull 注解修饰的变量。
若是参数不少,都在一个构造器里面,1、极不优雅,可读性不好,2、不良设计。
与这个注解相关的还有 AllArgsConstructor 注解,包括全部参数,仍是当心为妙。但在参数很少的时候仍是能够代替使用的,但对不熟悉的人来讲就是个潜在的问题。
2)@EqualsAndHashCode
Generates implementations for the {@code equals} and {@code hashCode} methods inherited by all objects, based on relevant fields.
这个注解用来生成 equals 和 hashCode 方法,里面有一个 callSuper() 方法:
/**
* Call on the superclass's implementations of {@code equals} and {@code hashCode} before calculating for the fields in this class.
* <strong>default: false</strong>
*
* @return Whether to call the superclass's {@code equals} implementation as part of the generated equals algorithm.
*/
boolean callSuper() default false;
是否调用父类的 equals 和 hashCode 方法,默认为:false 不调用,这也是引发问题的关键。
来看下面的例子:
@Data
public class BaseStudent {
private int id;
}
@Data
@AllArgsConstructor
public class Student extends BaseStudent {
private String name;
private int age;
private String address;
}
把生成的 equals 和 hashCode 方法反编译出来看下:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Student))
return false;
Student other = (Student)o;
if (!other.canEqual(this))
return false;
Object this$name = getName(), other$name = other.getName();
if ((this$name == null) ? (other$name != null) : !this$name.equals(other$name))
return false;
if (getAge() != other.getAge())
return false;
Object this$address = getAddress(), other$address = other.getAddress();
return !((this$address == null) ? (other$address != null) : !this$address.equals(other$address));
}
public int hashCode() {
int PRIME = 59;
result = 1;
Object $name = getName();
result = result * 59 + (($name == null) ? 43 : $name.hashCode());
result = result * 59 + getAge();
Object $address = getAddress();
return result * 59 + (($address == null) ? 43 : $address.hashCode());
}
最后判断若是不是同一个对象时,会判断每一个变量的值,可是此时父类的值不参与比较,这显然是不符合逻辑的,另外 hashCode 方法父类的值也没有参与运算,也是潜在问题。
使用 Lombok 能够帮助咱们少写不少代码,但同时也下降了代码可读性和跟踪、调试的问题。
好比,我想查找 getName() 方法都被哪些地方引用了,就不能直接按快捷键了,可能须要费一翻力气。
代码调试也有问题,好比我跟进 getAddress 方法,虽然进不去该方法,但能够直接跳到对应的变量,显示对应的值。
可是我想调试生成后的 hashCode 方法的运算过程,代码没有,断点都无法打,怎么调试?
即便如此,我以为这个问题不大,咱们不多去跟踪这些代码,咱们也能够经过其余方式来曲线解决。
以上一些问题都是使用 Lombok 不可避免的,这还只是已知的问题,未知的呢?
Lombok 虽好,你也要遵循团队的规范,能用的状况下再用,也不能乱用,不了解其构造,乱用就容易出现问题的。
最好的方法是,做用域最小化,须要什么就用什么,注解单独使用,而不是三七二十一什么类上来都来一个 @Data 什么的,出问题就欲哭无泪了。
全部种种潜在的问题都是领导者不肯意看到的,因此,有的公司是明令禁止使用 Lombok的,我我的是不沾边,适度运用就好,但不要过分依赖。
若是你还遇到其余使用 Lombok 的问题,欢迎留言分享~