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

本文介绍了Lombok如何通过注解简化Java开发,特别是get、set方法的生成,展示了其在提高代码简洁度方面的优势,同时也揭示了使用Lombok可能遇到的挑战,如队友依赖、调试难度提升、封装性破坏和兼容性风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、介绍

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

尤其是当一个实体类,高达几十个变量时,写完get、set方法之后,一个实体类的长度快接近一千行。
在这里插入图片描述

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

二、Lombok

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

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

在这里插入图片描述

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

<dependency> 
    <groupId>org.projectlombok</groupId> 
    <artifactId>lombok</artifactId> 
    <version>1.18.12</version> 
    <scope>provided</scope> 
</dependency> 

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

import lombok.Data;

@Data 
public class User { 
    private String id; 
    private String age; 
    private String name; 
  
 //可以不用显式写get、set方法 
} 

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

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

public class User { 
    private String id; 
    private String age; 
    private String name; 
 
    public User() { 
    } 
 
    public String getId() { 
        return this.id; 
    } 
 
    public String getAge() { 
        return this.age; 
    } 
 
    public String getName() { 
        return this.name; 
    } 
 
    public void setId(String id) { 
        this.id = id; 
    } 
 
    public void setAge(String age) { 
        this.age = age; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 
    public boolean equals(Object o) { 
        if (o == this) { 
            return true; 
        } else if (!(o instanceof User)) { 
            return false; 
        } else { 
            User other = (User)o; 
            if (!other.canEqual(this)) { 
                return false; 
            } else { 
                label47: { 
                    Object this$id = this.getId(); 
                    Object other$id = other.getId(); 
                    if (this$id == null) { 
                        if (other$id == null) { 
                            break label47; 
                        } 
                    } else if (this$id.equals(other$id)) { 
                        break label47; 
                    } 
 
                    return false; 
                } 
 
                Object this$age = this.getAge(); 
                Object other$age = other.getAge(); 
                if (this$age == null) { 
                    if (other$age != null) { 
                        return false; 
                    } 
                } else if (!this$age.equals(other$age)) { 
                    return false; 
                } 
 
                Object this$name = this.getName(); 
                Object other$name = other.getName(); 
                if (this$name == null) { 
                    if (other$name != null) { 
                        return false; 
                    } 
                } else if (!this$name.equals(other$name)) { 
                    return false; 
                } 
 
                return true; 
            } 
        } 
    } 
 
    protected boolean canEqual(Object other) { 
        return other instanceof User; 
    } 
 
    public int hashCode() { 
        int PRIME = true; 
        int result = 1; 
        Object $id = this.getId(); 
        int result = result * 59 + ($id == null ? 43 : $id.hashCode()); 
        Object $age = this.getAge(); 
        result = result * 59 + ($age == null ? 43 : $age.hashCode()); 
        Object $name = this.getName(); 
        result = result * 59 + ($name == null ? 43 : $name.hashCode()); 
        return result; 
    } 
 
    public String toString() { 
        return "User(id=" + this.getId() + ", age=" + this.getAge() + ", name=" + this.getName() + ")"; 
    } 
} 

很清晰的看到,使用@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被完全暴露在外界了。

public class User { 
 
    private String id; 
 
    private String age; 
 
    private String name; 
 
    private String tag = "学生"; 
 
    public String getTag() { 
        return tag; 
    } 
     
} 

3.5、影响 jdk 升级

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

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

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

四、总结

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

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

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

### 解决 Lombok `@Data` 注解不生效的方法 #### 安装并启用 Lombok 插件 为了使 Lombok 的功能正常工作,在 IntelliJ IDEA 中必须安装相应的插件。通过菜单栏中的 **File** -> **Settings** -> **Plugins** 来查找和安装 Lombok 插件[^2]。 #### 配置编译器支持 除了安装插件外,还需要确保 IDE 编译器能够识别 Lombok 提供的功能。这通常涉及到配置项目的构建工具(如 Maven 或 Gradle),以包含 Lombok 依赖项,并设置 JVM 参数来允许代理类加载机制。对于 Maven 用户来说,可以在 pom.xml 文件中加入如下片段: ```xml <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <!-- 版本号需根据实际情况调整 --> <scope>provided</scope> </dependency> ``` 而对于 Gradle,则应在 build.gradle 添加相应的内容: ```groovy dependencies { compileOnly 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.projectlombok:lombok:1.18.24' } ``` #### 检查项目结构与模块路径 有时即使正确设置了环境变量以及引入了必要的库文件,仍然会遇到问题。此时应该仔细检查整个工程目录下的 .iml 和其他配置文件是否有误;另外也要确认各个子模块之间的相互关系是否合理,特别是当存在多级嵌套的情况下更要注意这一点[^1]。 #### 清理缓存重新启动 IDE 最后一步也是最容易被忽视的一环就是清理本地磁盘上的临时数据,包括但不限于索引数据库、自动保存的工作副本等。具体操作可以通过点击右上角的 “Invalidate Caches / Restart...” 菜单项完成。这样做可以有效排除由于历史遗留因素所引发的各种异常状况[^4]。 #### 测试验证 经过上述处理之后,建议创建一个新的 Java 类尝试应用 `@Data` 注解,观察其自动生成 getter/setter 方法的效果如何。如果一切顺利的话,那么之前提到的问题也就迎刃而解了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monster_起飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值