Delombok 是个啥?居然可破 Lombok?

点击上方 果汁简历 ,选择“置顶公众号”

优质文章,第一时间送达

刚聊完《让人又爱又恨的 Lombok,到底该不该用》,里面提到了 Delombok 到底是个什么鬼?

Delombok 原本就是 Lombok 出的一个神器,可以让你使用一个命令把 Lombok 注解实现的类文件转换为不使用 LombokJava 源文件。如果是 src 整个目录,可以递归的实现转换,Delombok 会自动过滤非 Lombok 注解的文件进行原样拷贝。

Delombok 的出现让我们不仅可以了解到 Lombok 的实现内幕,还可以很好的做系统升级,比如要生成 javadoc 或者使用 Google Widget Toolkit 都是不支持  Lombok 的,这时候就可以使用 Delombok 进行反编译,同时也能解决我们使用 Lombok 升级 JDK 带来的不兼容问题。

话不多少直接 run 起来

  1. 环境准备

直接在官网下载 lombok.jarhttps://projectlombok.org/downloads/lombok.jar

  1. 项目准备

创建项目,分别编写 User.java 和 application.properties,UserMapper.xml ,User.java 是使用的 Lombok 的 Java 类,其余两个配置文件为了验证 Delombok 的功能,最后把刚才下载下来的 lombok.jar 放在项目的根目录。

其中 User.java 的文件如下
package com.github.juice.resume;

import lombok.*;

import java.io.FileInputStream;
import java.io.InputStream;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    private String id;
    private String name;
    private String desc;

    public static void main(String[] args) {

        // @NoArgsConstructor 生成
        new User();

        // @AllArgsConstructor 生成
        new User("juice-resume", "果汁简历", "专注于 Java 方向技术分享");

        // @Builder 生成
        User user = User.builder().id("juice-resume").name("果汁简历").desc("专注于 Java 方向技术分享").build();
    }

    // @SneakyThrows 自动生成 throws FileNotFoundException
    @SneakyThrows
    private void read() {
        // @Cleanup 相当于 inputStream.close();
        @Cleanup
        InputStream inputStream = new FileInputStream("");
    }

    /**
     * @Synchronized private final Object $lock = new Object[0];
     * public void write() {
     * synchronized(this.$lock) {
     * System.out.println("write");
     * }
     * }
     */

    @Synchronized
    public void write() {
        System.out.println("write");
    }
}
  1. 编写脚本

为了不影响原有的项目结构,同时还能保留反编译前的内容,所有我直接重命名 srcsrc-lombok,然后再从src-lomboksrc进行反编译,脚本如下

mv src src-lombok
java -jar lombok.jar delombok lombok-src -d src
  1. 运行脚本

运行脚本,然后检查目录

sh delombok.sh

运行命令以后我们可以检查结果,所有文件都被复制,但是User.java 文件被“反编译”了,如下

// Generated by delombok at Fri Jul 10 07:52:41 CST 2020
package com.github.juice.resume;

import lombok.*;
import java.io.FileInputStream;
import java.io.InputStream;

public class User {
    // @NoArgsConstructor 生成
    // @AllArgsConstructor 生成
    // @Builder 生成
    // @SneakyThrows 自动生成 throws FileNotFoundException
    // @Cleanup 相当于 inputStream.close();
    @java.lang.SuppressWarnings("all")
    private final java.lang.Object $lock = new java.lang.Object[0];
    private String id;
    private String name;
    private String desc;

    public static void main(String[] args) {
        new User();
        new User("juice-resume", "果汁简历", "专注于 Java 方向技术分享");
        User user = User.builder().id("juice-resume").name("果汁简历").desc("专注于 Java 方向技术分享").build();
    }

    private void read() {
        try {
            InputStream inputStream = new FileInputStream("");
            try {
            } finally {
                if (java.util.Collections.singletonList(inputStream).get(0) != null) {
                    inputStream.close();
                }
            }
        } catch (final java.lang.Throwable $ex) {
            throw lombok.Lombok.sneakyThrow($ex);
        }
    }

    /**
     * @Synchronized private final Object $lock = new Object[0];
     * public void write() {
     * synchronized(this.$lock) {
     * System.out.println("write");
     * }
     * }
     */
    public void write() {
        synchronized (this.$lock) {
            System.out.println("write");
        }
    }


    @java.lang.SuppressWarnings("all")
    public static class UserBuilder {
        @java.lang.SuppressWarnings("all")
        private String id;
        @java.lang.SuppressWarnings("all")
        private String name;
        @java.lang.SuppressWarnings("all")
        private String desc;

        @java.lang.SuppressWarnings("all")
        UserBuilder() {
        }

        @java.lang.SuppressWarnings("all")
        public User.UserBuilder id(final String id) {
            this.id = id;
            return this;
        }

        @java.lang.SuppressWarnings("all")
        public User.UserBuilder name(final String name) {
            this.name = name;
            return this;
        }

        @java.lang.SuppressWarnings("all")
        public User.UserBuilder desc(final String desc) {
            this.desc = desc;
            return this;
        }

        @java.lang.SuppressWarnings("all")
        public User build() {
            return new User(this.id, this.name, this.desc);
        }

        @java.lang.Override
        @java.lang.SuppressWarnings("all")
        public java.lang.String toString() {
            return "User.UserBuilder(id=" + this.id + ", name=" + this.name + ", desc=" + this.desc + ")";
        }
    }

    @java.lang.SuppressWarnings("all")
    public static User.UserBuilder builder() {
        return new User.UserBuilder();
    }

    @java.lang.SuppressWarnings("all")
    public String getId() {
        return this.id;
    }

    @java.lang.SuppressWarnings("all")
    public String getName() {
        return this.name;
    }

    @java.lang.SuppressWarnings("all")
    public String getDesc() {
        return this.desc;
    }

    @java.lang.SuppressWarnings("all")
    public void setId(final String id) {
        this.id = id;
    }

    @java.lang.SuppressWarnings("all")
    public void setName(final String name) {
        this.name = name;
    }

    @java.lang.SuppressWarnings("all")
    public void setDesc(final String desc) {
        this.desc = desc;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof User)) return false;
        final User other = (User) o;
        if (!other.canEqual((java.lang.Object) this)) return false;
        final java.lang.Object this$id = this.getId();
        final java.lang.Object other$id = other.getId();
        if (this$id == null ? other$id != null : !this$id.equals(other$id)) return false;
        final java.lang.Object this$name = this.getName();
        final java.lang.Object other$name = other.getName();
        if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
        final java.lang.Object this$desc = this.getDesc();
        final java.lang.Object other$desc = other.getDesc();
        if (this$desc == null ? other$desc != null : !this$desc.equals(other$desc)) return false;
        return true;
    }

    @java.lang.SuppressWarnings("all")
    protected boolean canEqual(final java.lang.Object other) {
        return other instanceof User;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final java.lang.Object $id = this.getId();
        result = result * PRIME + ($id == null ? 43 : $id.hashCode());
        final java.lang.Object $name = this.getName();
        result = result * PRIME + ($name == null ? 43 : $name.hashCode());
        final java.lang.Object $desc = this.getDesc();
        result = result * PRIME + ($desc == null ? 43 : $desc.hashCode());
        return result;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString() {
        return "User(id=" + this.getId() + ", name=" + this.getName() + ", desc=" + this.getDesc() + ")";
    }

    @java.lang.SuppressWarnings("all")
    public User() {
    }

    @java.lang.SuppressWarnings("all")
    public User(final String id, final String name, final String desc) {
        this.id = id;
        this.name = name;
        this.desc = desc;
    }
}

所以你学到了吗?

往期精彩回顾

美团技术大佬写给工程师的十条精进原则

为什么优秀的程序员都写博客?

29 岁成为阿里巴巴 P8,工作前 5 年完成晋升 3 连跳,他如何做到?

点个赞呗

<think>嗯,用户问的是Lombok是什么。我需要先回想一下自己对Lombok的了解。记得它是一个Java库,用来减少样板代码。比如,自动生成getter、setter这些方法。开发者通过注解来简化代码,不需要手动写重复的部分。 那用户可能想知道Lombok的作用、为什么需要它,以及怎么用。我应该从这些方面入手。先介绍Lombok的基本概念,然后说明它的主要功能,比如常用注解,比如@Data、@Getter、@Setter这些。还需要提到它如何提升开发效率,减少代码量,让代码更简洁。 可能用户是Java开发者,遇到重复代码的问题,或者听别人提到Lombok,想了解它能解决什么问题。要注意解释它的工作原理,比如在编译时处理注解,生成字节码,这样运行时不需要依赖。同时,可能存在的争议点,比如对IDE的支持,需要项目组员都安装插件,或者是否隐藏了底层代码可能带来的理解难度。 还要举例子说明,比如没有Lombok时,一个类需要写很多getter和setter方法,用了Lombok之后,只需要一个@Data注解。这样代码更易读,维护更方便。不过也要提醒潜在的注意事项,比如过度使用可能导致问题,或者团队协作时的配置要求。 最后,总结Lombok的优缺点,帮助用户判断是否适合他们的项目。可能用户需要权衡减少代码的好处和引入新依赖的风险。确保回答结构清晰,分点说明,让用户能逐步理解。</think>Lombok 是一个用于简化 Java 开发的工具库,其核心目标是**通过注解自动生成重复性代码**,从而减少开发者的手动编码量。以下是其关键特性的分步解析: --- ### 1. **核心原理** - **编译时注解处理**:Lombok 在 Java 编译阶段通过注解处理器(Annotation Processor)自动生成代码(如 getter、setter 等),生成的代码会直接写入字节码文件,**源码本身不会改变**。 - **无运行时依赖**:生成的代码在编译后即存在,因此项目运行时无需依赖 Lombok 库。 --- ### 2. **常用注解与功能** #### 基础功能 - `@Getter` / `@Setter`:自动生成字段的 getter 和 setter 方法。 ```java @Getter @Setter public class User { private String name; } // 自动生成 getName() 和 setName(String name) ``` - `@ToString`:自动生成 `toString()` 方法,可排除特定字段。 ```java @ToString(exclude = "password") public class User { /*...*/ } ``` - `@EqualsAndHashCode`:生成 `equals()` 和 `hashCode()` 方法。 #### 高阶功能 - `@Data`:**组合注解**,包含 `@Getter`、`@Setter`、`@ToString`、`@EqualsAndHashCode` 和构造方法。 ```java @Data public class User { private String name; private int age; } ``` - `@Builder`:为类生成链式构造器(Builder 模式)。 ```java @Builder public class User { private String name; } // 使用:User.builder().name("Alice").build(); ``` - `@Slf4j`:自动生成日志对象(如 `log.info(...)`)。 --- ### 3. **使用 Lombok 的优势** - **代码简洁性**:减少手动编写重复代码(如 POJO 类的模板代码)。 - **可维护性**:字段变更时无需手动修改相关方法(如新增字段后,`toString()` 自动更新)。 - **开发效率**:专注于业务逻辑而非模板代码。 --- ### 4. **潜在注意事项** - **IDE 兼容性**:需安装 Lombok 插件(如 IntelliJ IDEA、Eclipse)以支持注解的识别和代码提示。 - **代码可读性**:过度使用可能导致开发者对生成的方法缺乏直观理解。 - **团队协作**:需确保所有成员配置相同的开发环境。 --- ### 5. **适用场景** - **POJO/DTO 类**:快速定义数据模型。 - **单元测试**:简化测试对象的构建。 - **日志管理**:避免手动声明日志对象。 --- ### 6. **如何开始使用** 1. **添加依赖**(Maven 示例): ```xml <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <scope>provided</scope> </dependency> ``` 2. **安装 IDE 插件**(如 IntelliJ 的 Lombok Plugin)。 3. 在类或字段上添加注解即可。 --- ### 总结 Lombok 通过**“约定优于配置”**的理念,显著提升 Java 开发效率,尤其适合需要频繁定义数据模型的场景。但需结合团队规范谨慎使用,避免因过度依赖注解导致代码可读性下降。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值