【优雅代码】01-lombok精选注解及原理

简介: lombok与delombok

【优雅代码】01-lombok精选注解及原理

欢迎关注b站账号/公众号【六边形战士夏宁】,一个要把各项指标拉满的男人。该文章已在 github目录收录。
屏幕前的 大帅比大漂亮如果有帮助到你的话请顺手点个赞、加个收藏这对我真的很重要。别下次一定了,都不关注上哪下次一定。

1.背景介绍

在日常开发中免不了进行一些繁琐的代码自动生成,虽然ide的功能已然非常强大但是并不能够做到动态,lombok可以非常好的解决这个问题。它会在生成class文件时将其进行编译成平常所写的代码,这里介绍一些我个人觉得比较好用的注解

2.lombok

先上官网地址。如果想了解更多注解可以去https://projectlombok.org/features/all

2.1.get/set注解(重要)

此部分注解有@Data、@Getter、@Setter,一般普通Bean对象会使用@Data注解(里面已经包含另外两个注解),如果是enum则使用@Getter注解

@Data
static class DataBean {
    private String name;
}
// 使用方法如下
public static void DataBeanExample() {
    log.info(new DataBean().getName());
}

生成核心代码如下

static class DataBean {
    private String name;

    public DataBean() {
    }

    public String getName() {
        return this.name;
    }

    public void setName(final String name) {
        this.name = name;
    }
    ...
}

2.2.常规构造方法注解(重要)

此部分注解包含@NoArgsConstructor无参构造、@AllArgsConstructor所有参构造、@EqualsAndHashCode、@ToString

@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
static class ConstructorBean {
    private String name1;
    private String name2;
}
// 使用方法如下
public static void ConstructorExample() {
    log.info(new ConstructorBean("1", "2").toString());
}

生成核心代码如下

static class ConstructorBean {
    private String name1;
    private String name2;

    public ConstructorBean() {
    }

    public ConstructorBean(final String name1, final String name2) {
        this.name1 = name1;
        this.name2 = name2;
    }

    public boolean equals(final Object o) {
        //....
    }

    protected boolean canEqual(final Object other) {
        return other instanceof LombokExample.ConstructorBean;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $name1 = this.name1;
        int result = result * 59 + ($name1 == null ? 43 : $name1.hashCode());
        Object $name2 = this.name2;
        result = result * 59 + ($name2 == null ? 43 : $name2.hashCode());
        return result;
    }

    public String toString() {
        return "LombokExample.ConstructorBean(name1=" + this.name1 + ", name2=" + this.name2 + ")";
    }
}

2.4.build构造方法(重要)

此部分注解包含@Builder

@Builder
@ToString
static class BuilderBean {
    private String name1;
    private String name2;
}
// 使用方式如下
public static void BuilderExample() {
    log.info(BuilderBean.builder().name1("1").name2("2").build().toString());
}

生成核心代码如下

static class BuilderBean {
    private String name1;
    private String name2;

    BuilderBean(final String name1, final String name2) {
        this.name1 = name1;
        this.name2 = name2;
    }

    public static LombokExample.BuilderBean.BuilderBeanBuilder builder() {
        return new LombokExample.BuilderBean.BuilderBeanBuilder();
    }

    public String toString() {
        return "LombokExample.BuilderBean(name1=" + this.name1 + ", name2=" + this.name2 + ")";
    }

    public static class BuilderBeanBuilder {
        private String name1;
        private String name2;

        BuilderBeanBuilder() {
        }

        public LombokExample.BuilderBean.BuilderBeanBuilder name1(final String name1) {
            this.name1 = name1;
            return this;
        }

        public LombokExample.BuilderBean.BuilderBeanBuilder name2(final String name2) {
            this.name2 = name2;
            return this;
        }

        public LombokExample.BuilderBean build() {
            return new LombokExample.BuilderBean(this.name1, this.name2);
        }

        public String toString() {
            return "LombokExample.BuilderBean.BuilderBeanBuilder(name1=" + this.name1 + ", name2=" + this.name2 + ")";
        }
    }
}

2.5.链式构造方法

此部分注解包含@Accessors,但是因为改写了set方法的返回值,有些时候会和其它bean工具类不兼容,一般不建议使用

@Accessors(chain = true)
@Setter
@ToString
static class ChainBean {
    private String name1;
    private String name2;
}
// 使用方式如下
public static void ChainExample() {
    log.info(new ChainBean().setName1("1").setName2("2").toString());
}

生成核心代码如下

static class ChainBean {
    private String name1;
    private String name2;

    ChainBean() {
    }

    public LombokExample.ChainBean setName1(final String name1) {
        this.name1 = name1;
        return this;
    }

    public LombokExample.ChainBean setName2(final String name2) {
        this.name2 = name2;
        return this;
    }

    ...
}

2.6.日志注解(重要)

此部分注解包含@Slf4j,其它的注解都不重要,这个会自动根据引入包进行选择

@Slf4j
public class LombokExample {
    public static void main(String[] args) {
        log.info("123");
    }
}

生成核心代码如下

private static final Logger log = LoggerFactory.getLogger(LombokExample.class);

2.7.关闭流

@Cleanup,这个可以帮助关闭流,需要注意的是需要对其捕获IO异常。虽然不错,但是有了trywith的写法以后就用的不多了。

public static void CloseExample() throws FileNotFoundException {
    try {
        @Cleanup FileInputStream fileInputStream = new FileInputStream("");
    } catch (IOException e) {

    }
}

生成核心代码如下
可以看到会帮我们进行close。不过并没有在finally里面不建议使用

public static void CloseExample() throws FileNotFoundException {
    try {
        FileInputStream fileInputStream = new FileInputStream("");
        if (Collections.singletonList(fileInputStream).get(0) != null) {
            fileInputStream.close();
        }
    } catch (IOException var1) {
    }

}

这里推荐try-with-resources写法

public static void CloseExample2() {
    try (FileInputStream fileInputStream = new FileInputStream("")) {
        log.info("123");
    } catch (IOException e) {

    }
}

生成核心代码如下
可以看到是在finally里面关闭了流,并且各种判断非常全面

public static void CloseExample2() {
    try {
        FileInputStream fileInputStream = new FileInputStream("");
        Throwable var1 = null;

        try {
            log.info("123");
        } catch (Throwable var11) {
            var1 = var11;
            throw var11;
        } finally {
            if (fileInputStream != null) {
                if (var1 != null) {
                    try {
                        fileInputStream.close();
                    } catch (Throwable var10) {
                        var1.addSuppressed(var10);
                    }
                } else {
                    fileInputStream.close();
                }
            }

        }
    } catch (IOException var13) {
    }

}

2.8.异常注解

在捕获编译时异常的时候比较好用,但是现在越来越多的工具类都对编译异常捕获了,它的出场机会并不多

@SneakyThrows({IOException.class})
public static void ExceptionExample() {
    CloseExample();
}

生成核心代码如下
唯一的功能就是捕获编译时异常,不用手动去写

public static void ExceptionExample() {
    try {
        CloseExample();
    } catch (IOException var1) {
        throw var1;
    }
}

3.delombok

如果后面不想用注解则需要使用delombok官网

  • 方法一

在新版的idea中refactor->delombok已经集成了delombok,可以直接还原算是比较方便的
delombok

  • 方法二
java -jar lombok.jar delombok src -d src-delomboked

注意替换包名

相关文章
|
30天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
64 7
|
13天前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
26 3
|
13天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
37 3
|
13天前
|
安全 算法 Java
Java CAS原理和应用场景大揭秘:你掌握了吗?
CAS(Compare and Swap)是一种乐观锁机制,通过硬件指令实现原子操作,确保多线程环境下对共享变量的安全访问。它避免了传统互斥锁的性能开销和线程阻塞问题。CAS操作包含三个步骤:获取期望值、比较当前值与期望值是否相等、若相等则更新为新值。CAS广泛应用于高并发场景,如数据库事务、分布式锁、无锁数据结构等,但需注意ABA问题。Java中常用`java.util.concurrent.atomic`包下的类支持CAS操作。
44 2
|
21天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
57 2
|
1月前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
82 5
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
57 5
|
1月前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
IDE Java API
Lombok:让JAVA代码更优雅
Lombok:让JAVA代码更优雅
115 0
Lombok:让JAVA代码更优雅
|
Java 开发工具 IDE