Lombok使用总结

2023-05-16

文章目录

    • 介绍
    • Lombok原理
    • 常用注解
      • @Data
      • @Getter
      • @Setter
      • @ToString
      • @EqualsAndHashCode
      • @NoArgsConstructor
      • @AllArgsConstructor
      • @RequiredArgsConstructor
      • @Accessors(chain = true)
      • @Cleanup
      • @Builder
    • 遇到的问题
      • 谨慎使用@Data
        • 问题
        • 总结
      • @Builder和@Data不能共用
        • 解决

介绍

官网:https://projectlombok.org/

Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不需要再写getter、setter或equals方法,只要有一个注解,你的类就有一个功能齐全的构建器、自动记录变量等等。
可以精简我们的代码的,让开发人员把精力放在业务上。

Lombok原理

Java的编译分为以下⼏个阶段:

解析与填充符号表->注解处理->分析与字节码⽣成->⽣成⼆进制class⽂件。

Lombok 使⽤的是 JDK 6 实现的 JSR 269: Pluggable Annotation Processing API (编译期的注解处理器),它是在编译期时把 Lombok 的注解代码,转换为常规的 Java ⽅法⽽实现注⼊。
在编译期阶段,当 Java 源码被抽象成语法树 (AST) 之后,Lombok 会根据⾃⼰的注解处理器动态的修改AST,增加新的代码 (节点),在这⼀切执⾏之后,再通过分析⽣成了最终的字节码 (.class) ⽂件,这就是Lombok 的执⾏原理

常用注解

@Data

为我们的实体类自动生成get、set、hashcode、equals 、toString方法 与不带参数的构造方法。
它是一个混合注释,它包含了@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode的功能。

@Getter

生成get方法

@Setter

生成set方法

@ToString

生成toString方法

@EqualsAndHashCode

生成equals和hashCode方法

@NoArgsConstructor

生成无参构造

@AllArgsConstructor

生成有参构造

@RequiredArgsConstructor

生成有参构造,对于标有@NonNull注解的字段,还将生成一个显式的null检查

@Accessors(chain = true)

指定set方法通过this返回自己本身,以便于进行级联操作的执行。

@Cleanup

放在本地变量的声明前,自动产生close相关操作,例如IO流

@Builder

生成builder相关操作,方便通过builder的方式创建对象

遇到的问题

总结日常开发使用过程中遇到的问题

谨慎使用@Data

问题

子类不能完全代表父类
@EqualsAndHashCode注解里有个字段callSuper,它的默认值是false,意思是在重写时,不会将父类的字段写到equals里;而@Data这个注解由于包含了@EqualsAndHashCode,所以它也有这个特性,即子类强制实现了重写equals和hashCode,并且只重写了自己的属性,这时,问题就来了,当两个对象比较时,如果子类属性相同而父类属性不同,结果也为true,这是非常严重的bug。

总结

在使用@Data时,我们尽量把 @EqualsAndHashCode(callSuper = true)加上,因为你不加,它相当于是false;或者杜绝使用@Data,而用@Getter,@Setter,@ToString代替它。
具体还要取决于您的类层次结构,需要根据具体情况进行检查。

@Builder和@Data不能共用

由于添加@Builder会将@Data让类缺失无参构造器,因为很多框架都会调⽤⽆参构造去创建对象,所以会报错。

举例,使用Mybatis plus + Lombok查询数据时,会报下面的错误:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: java.lang.IndexOutOfBoundsException: Index 8 out of bounds for length 8

Caused by: java.lang.IndexOutOfBoundsException: Index 8 out of bounds for length 8
java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
java.base/java.util.Objects.checkIndex(Objects.java:372)
java.base/java.util.ArrayList.get(ArrayList.java:458)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createUsingConstructor(DefaultResultSetHandler.java:709)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createByConstructorSignature(DefaultResultSetHandler.java:694)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:658)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:631)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:398)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:355)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:329)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:302)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:195)
org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:67)
org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:163)
com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:111)
org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
com.sun.proxy.$Proxy425.query(Unknown Source)
org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)

解决

方法一,
在无参构造函数上加上@Tolerate即可解决,目的是让Lombok在⽣成类的时候,对指定的构造函数不感知。

方法二,
直接使用无参构造器+有参构造器的方式,类上添加注解@RequiredArgsConstructor 来构建有参,添加注解@NoArgsConstructor来构建无参构造器,即可解决。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lombok使用总结 的相关文章

  • firewall-cmd 使用总结

    firewalld的简要说明 firewalld firewall cmd firewall offline cmd它们Python脚本 xff0c 通过定义的在 usr lib firewalld下面的xml配置信息 xff0c 在启动时
  • 记lombok插件builder模式的一个坑

    使用lombok的builder模式时 如果属性有指定的默认值 不能使用静态的builder build 创建对象 正解见下文 一个坑 最近接手了一套代码 代码中的数据库表id用了UUID 有如下一个实体 import java util
  • Eclipse安装LomBok插件

    1 使用LomBok的好处在于实体类不用手动去生成set get方法了 类会在编译时自动生成 是代码简洁节省工作量 2 maven项目的pom文件添加坐标下载
  • Lombok插件注解详解

    Lombok主要常用的注解 Data注解 在JavaBean或类JavaBean中使用 这个注解包含范围最广 它包含getter setter NoArgsConstructor注解 即当使用当前注解时 会自动生成包含的所有方法 Gette
  • 无法使用lombok构建maven jhipster项目

    mvnw 和 mvn clean install 在添加 lombok 依赖项时失败 但从 Intellij IDE 启动时成功运行 找到下面的错误 INFO ERROR COMPILATION ERROR INFO ERROR src m
  • 有没有办法为@AllArgsConstructor(lombok)的所有参数设置“not null”

    我正在使用 AllArgsConstructor我的类中的注释并希望确保参数不为空 有没有办法修改这个注释来实现这一点 或者我应该实现构造函数 谢谢 Getter Setter ToString AllArgsConstructor pub
  • 注释顺序重要吗?

    如您所知 注释驱动编程越来越多地融入到我们现在使用的大多数框架中 即 Spring Lombok 等 此外 我们有时需要创建自定义注释 例如 使用切面记录给定类的所有公共方法的进入 退出跟踪 LogAroundMethods 因此 给定的类
  • Lombok @Wither/@With Inheritance(超/子类)

    请建议如何使用 Wither With当继承应用时 我有一个抽象类Parent和混凝土Child Child应该是不可变的 推杆 Wither两者都给了我两个错误 构造函数 Child String 未定义 Child 类型必须实现继承的抽
  • Java SneakyThrow 异常、类型擦除

    有人可以解释一下这段代码吗 public class SneakyThrow public static void sneakyThrow Throwable ex SneakyThrow
  • 如何在 Lombok 中调用超级构造函数

    我有课 Value NonFinal public class A int x int y 我还有一个B班 Value public class B extends A int z lombok 抛出错误 说它找不到 A 构造函数 显式调用
  • Java Lombok:省略 @AllArgsConstructor 中的一个字段?

    如果我指定 AllArgsConstructor using Lombok 它将生成一个构造函数来设置所有声明的 非最终的 非静态的 字段 是否可以省略某些字段并为所有其他字段留下生成的构造函数 不 那是不可能的 有一个创建功能请求 Som
  • 如何修复:IntelliJ 中似乎无法识别 Lombok builder() 方法?

    我不确定我做错了什么 有人可以帮我吗 POM Implementation Using it as below builder 方法似乎无法被识别 我正在使用 IntelliJ 我有什么遗漏的吗 以下是我的智能设置 除了依赖于provide
  • Lombok 不生成 getters/setters(使用 Luna 或命令行编译)

    我第一次尝试龙目岛 我尝试尽可能地遵循指示 但是当我查看编译的类 使用反编译器 时 它们没有任何生成的 getter 或 setter 我的安装步骤 下载lombok 1 14 8并运行java jar lombok jar 它将 lomb
  • 如何忽略 Jacoco 的 lombok.@UtilityClass?

    我用过lombok UtilityClass to 生成私有构造函数 使班级最终 将实用程序类中的所有字段设为静态 并且 Jacoco 不涵盖 Lombok 生成的代码 如果我显式定义一个私有构造函数 Jacoco 可以识别它 因此 有任何
  • 使用辅助方法为 Java 对象生成测试数据时提供默认值

    假设有以下 POJO Getter Setter public class UserRequest private String username private String password private String email 现
  • 添加了 Lombok,但 Intellij IDEA 无法识别 getter 和 setter

    我在 ubuntu 上使用 IntelliJ IDEA 我添加了龙目岛 jar进入我的项目并安装 IDEA 的 Lombok 插件 我可以访问注释 但是getters and setters没有生成 如果我尝试访问不存在的 getter 或
  • Lombok/Jackson - 用于 json 数组的 POJO

    我有一个 json 数组 需要从服务器接收 反序列化 并将其发送 序列化 到另一台服务器 Example car name string parts engine wheels 我开始编写以下 POJO 来表示这个 Json 数组 impo
  • 如何在 eclipse luna 中配置 lombok

    我使用 Maven 在 eclipse Luna 中配置 lombok 注解已正确添加 但未生成 getter 和 setter eclipse ini vm E Program Files Java jdk1 7 0 60 bin vma
  • Kotlin 看不到 Java Lombok 访问器?

    使用 Kotlin 1 0 0 版本 在 IntelliJ 15 中编译 println myPojoInstance foo 当它尝试编译引用基于 Lombok 的 POJO 的代码 在 IntelliJ 或 Gradle 中 时 它会给
  • 龙目岛和吉斯注射液

    我是 lombok 和 guice 注入的新手 我可以了解一般概念 但我遇到了一些我不理解的代码 并且由于语法而无法搜索 以下是代码 有人可以帮助我理解吗 import com google inject Inject import lom

随机推荐