公司来了个新同事不会用 Lombok,还说我代码有问题!

简介: 最近公司新来一个搞 Java 的同事,搞了半天项目还没有跑起来,后来叫我过去帮他看一下,然后指着红色的编译错误和我说是不是代码有问题。。

新来的同事不会用 Lombok,所以会引发本文!


背景

最近公司新来一个搞 Java 的同事,搞了半天项目还没有跑起来,后来叫我过去帮他看一下,然后指着红色的编译错误和我说是不是代码有问题。。


我顿时就心想,这人是不是太水了啊,工作三年了,简单的编译问题都搞不定?但是当我认真看了错误之后,发现……他竟然没装 Lombok 插件……


然后我和他说出了问题所在,让他安装下 Lombok 插件再重新编译下,他居然和我说不知道什么插件,感觉他没用过吧,甚至都没有听说过。


好吧,我认了,我默默亲自为他把 Lombok 装上了!


如果你没用过,我也不觉得奇怪,Lombok 毕竟是团队工具,但如果你也没听过,那就感觉获取新知识自我提升学习的能力有点弱了,或者不怎么看公众号。


当然,本篇不是教你怎么用 Lombok,因为我之前就已经写过教程分享过了,不会的可以点击这个链接看下,还热乎着呢。


放弃 Lombok?

因为,最近,栈长也有看到一些公众号在发放弃 Lombok 的文章,再结合最近一个新同事的情况,也谈谈到底要不要用 Lombok。


一味地劲大家放弃,我感觉有点偏激了,任何事物,存在就即合理,关键是利弊权衡的问题罢了。


用不用 Lombok,又是分两派,公说公有理,婆说婆有理,仁者见仁,智者见智,谁也说服不了谁,类似 Eclipse 和 IntelliJ IDEA 谁更好用之争!


我想说,争这些没任何意义,这完全取决于团队的决策,取决于你的团队能不能 Hold 住这个东西,如果利 > 弊,用它就对了,如果弊 > 利,那就考虑放弃吧。


如果你是个人项目,请大胆用吧!


Lombok 的弊端

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 的注解,否则会显示编译报错。如果你对 IDEA 还不会使用可以关注Java技术栈公众号在后台回复IDEA获取系列教程。


IntelliJ IDEA 插件示例:


image.png

如果某一个人为了方便自己而使用,其他人不愿意使用或者被迫使用,将导致团队其他成员代码没法正常编译,这也是问题的关键所在。


还有就是文章之前说的,来了一个新同事,如果他没有相应的使用经验,就需要额外的指导,对于老员工来说无疑也是一个额外的工作量。


二、@Data 注解的坑

@Data 注解用在类上,等同于下面这几个注解合集:

image.png

@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 注解修饰的变量。


如果参数很多,都在一个构造器里面,一、极不优雅,可读性很差,二、不良设计。


与这个注解相关的还有 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;

是否调用父类的 equalshashCode 方法,默认为:false 不调用,这也是引起问题的关键。

来看下面的例子:

@Data
public class BaseStudent {
    private int id;
}
@Data
@AllArgsConstructor
public class Student extends BaseStudent {
    private String name;
    private int age;
    private String address;
}

把生成的 equalshashCode 方法反编译出来看下:

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 方法,虽然进不去该方法,但可以直接跳到对应的变量,显示对应的值。

image.png

但是我想调试生成后的 hashCode 方法的运算过程,代码没有,断点都没法打,怎么调试?


即使如此,我觉得这个问题不大,我们很少去跟踪这些代码,我们也可以通过其他方式来曲线解决。


总结

以上一些问题都是使用 Lombok 不可避免的,这还只是已知的问题,未知的呢?


Lombok 虽好,你也要遵循团队的规范,能用的情况下再用,也不能乱用,不了解其构造,乱用就容易出现问题的。


最好的方法是,作用域最小化,需要什么就用什么,注解单独使用,而不是三七二十一什么类上来都来一个 @Data 什么的,出问题就欲哭无泪了。


所有种种潜在的问题都是领导者不愿意看到的,所以,有的公司是明令禁止使用 Lombok 的,我个人是不站边,适度运用就好,但不要过度依赖。



image.pngimage.png

相关文章
|
8天前
|
Java
lombok的使用
本文介绍了Lombok库的基本使用方法和常用注解,通过示例代码展示了如何使用Lombok简化Java对象的创建、属性访问、日志记录等编码工作,使代码更加简洁。
lombok的使用
|
22小时前
|
Java 数据处理 开发者
Java中的Lambda表达式:简化你的代码之路
【8月更文挑战第66天】Lambda表达式在Java 8中首次引入,它为Java开发者提供了一种更简洁、更灵活的编程方式。本文将通过简单易懂的语言和实际代码示例,引导你理解Lambda表达式的基本概念、语法结构以及如何在Java项目中应用它来简化代码。无论你是Java新手还是有经验的开发者,这篇文章都将帮助你更好地掌握这一强大的工具。
28 11
|
18天前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
7天前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
20 5
|
9天前
|
Java API 开发者
探索Java中的Lambda表达式:简洁与强大的代码实践
本文深入探讨Java中Lambda表达式的定义、用法及优势,通过实例展示其如何简化代码、提升可读性,并强调在使用中需注意的兼容性和效率问题。Lambda作为Java 8的亮点功能,不仅优化了集合操作,还促进了函数式编程范式的应用,为开发者提供了更灵活的编码方式。
|
5天前
|
Java 开发者
探索Java中的Lambda表达式:简化你的代码之旅##
【8月更文挑战第62天】 Java 8的发布为开发者带来了诸多新特性,其中最引人注目的无疑是Lambda表达式。这一特性不仅让代码变得更加简洁,还极大地提升了开发的效率。本文将通过实际示例,展示如何利用Lambda表达式来优化我们的代码结构,同时探讨其背后的工作原理和性能考量。 ##
|
8天前
|
Java API 开发者
探索Java中的Lambda表达式:简化代码,提升效率
【9月更文挑战第27天】在Java 8中引入的Lambda表达式为编程带来了革命性的变化。通过简洁的语法和强大的功能,它不仅简化了代码编写过程,还显著提升了程序的执行效率。本文将深入探讨Lambda表达式的本质、用法和优势,并结合实例演示其在实际开发中的应用。无论你是Java新手还是资深开发者,都能从中获得启发,优化你的代码设计。
|
9天前
|
Java Linux Python
Linux环境下 代码java调用python出错
Linux环境下 代码java调用python出错
24 3
|
8天前
|
存储 Java 索引
使用java代码实现左右括号查找
使用java代码实现左右括号查找
|
9天前
|
算法 Java
java 概率抽奖代码实现
java 概率抽奖代码实现
下一篇
无影云桌面