当前位置: 首页 > news >正文

Lombok 简单讲解

参考

https://blog.csdn.net/ThinkWon/article/details/101392808
https://www.baeldung.com/intro-to-project-lombok
https://projectlombok.org/features/

介绍

Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.

添加依赖:

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

在 idea 中需要确保安装了 Lombok 插件。

基本用法

生成 get 和 set 方法

使用 Lombok 的 @Getter 和 @Setter 方法,可以自动为我们生成 get 和 set 方法。

import lombok.Getter;
import lombok.Setter;public class Person {@Getter@Setterprivate String name;private int age;private String address;
}

编译后的代码:

public class Person {private String name;private int age;private String address;public Person() {}public String getName() {return this.name;}public void setName(String name) {this.name = name;}
}

toString 方法

使用 Lombok 中的 @ToString 方法会自动为我们生成 toString 方法。

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;@ToString
public class Person {@Getter@Setterprivate String name;private int age;private String address;
}

编译后的代码:

public class Person {private String name;private int age;private String address;public Person() {}public String toString() {return "Person(name=" + this.getName() + ", age=" + this.age + ", address=" + this.address + ")";}public String getName() {return this.name;}public void setName(String name) {this.name = name;}
}

equals 和 hashCode 方法

@EqualsAndHashCode 注解会同时生成 equals 方法和 hashCode 方法。

@EqualsAndHashCode
public class Address {private String street;private String city;private String state;private String postalCode;
}

编译后的代码:

public class Address {private String street;private String city;private String state;private String postalCode;public Address() {}public boolean equals(Object o) {if (o == this) {return true;} else if (!(o instanceof Address)) {return false;} else {Address other = (Address)o;if (!other.canEqual(this)) {return false;} else {label59: {Object this$street = this.street;Object other$street = other.street;if (this$street == null) {if (other$street == null) {break label59;}} else if (this$street.equals(other$street)) {break label59;}return false;}Object this$city = this.city;Object other$city = other.city;if (this$city == null) {if (other$city != null) {return false;}} else if (!this$city.equals(other$city)) {return false;}Object this$state = this.state;Object other$state = other.state;if (this$state == null) {if (other$state != null) {return false;}} else if (!this$state.equals(other$state)) {return false;}Object this$postalCode = this.postalCode;Object other$postalCode = other.postalCode;if (this$postalCode == null) {if (other$postalCode != null) {return false;}} else if (!this$postalCode.equals(other$postalCode)) {return false;}return true;}}}protected boolean canEqual(Object other) {return other instanceof Address;}public int hashCode() {int PRIME = true;int result = 1;Object $street = this.street;result = result * 59 + ($street == null ? 43 : $street.hashCode());Object $city = this.city;result = result * 59 + ($city == null ? 43 : $city.hashCode());Object $state = this.state;result = result * 59 + ($state == null ? 43 : $state.hashCode());Object $postalCode = this.postalCode;result = result * 59 + ($postalCode == null ? 43 : $postalCode.hashCode());return result;}
}

构造方法

@NoArgsConstructor:生成无参构造方法。
@AllArgsConstructor:生成所有字段的构造方法。
@RequiredArgsConstructor:当你在一个类中使用 @RequiredArgsConstructor 注解时,Lombok 会自动帮你生成一个构造函数,该构造函数仅包含类中定义的 final 字段或者被 @NonNull 注解标记的字段。

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;@AllArgsConstructor
@NoArgsConstructor
public class Employee {private int id;private String name;private String department;private double salary;
}

编译后的 java 代码:

public class Employee {private int id;private String name;private String department;private double salary;public Employee(int id, String name, String department, double salary) {this.id = id;this.name = name;this.department = department;this.salary = salary;}public Employee() {}
}
import lombok.NonNull;
import lombok.RequiredArgsConstructor;import java.util.List;@RequiredArgsConstructor
public class Order {private final int orderId;private List<String> products;@NonNullprivate double totalPrice;
}

编译后的代码:

import com.jxd.bug.Product;
import java.util.List;
import lombok.NonNull;public class Order {private final int orderId;private List<Product> products;private @NonNull double totalPrice;public Order(int orderId, @NonNull double totalPrice) {this.orderId = orderId;this.totalPrice = totalPrice;}
}

高级用法

日志

lombok 提供了 @Slf4j、@Log、@CommonsLog、@Log4j、@Log4j2、@XSlf4j、@Slf4j 这些日志注解来对应不同的日志框架。

import lombok.extern.slf4j.Slf4j;/*** @author jxd* {@code @date} 2024/3/26 21:47*/
@Slf4j
public class Log {public static void main(String[] args) {log.info("@Slf4j annotation");}
}

编译后的代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class Log {private static final Logger log = LoggerFactory.getLogger(Log.class);public Log() {}public static void main(String[] args) {log.info("@Slf4j annotation");}
}

@Data 注解

相当于这些注解的一个聚合:

  • @ToString
  • @EqualsAndHashCode
  • @Getter
  • @Setter
  • @RequiredArgsConstructor

@Builder 注解

@Builder 注解会自动为我们生成 bean 对应的 Builder,有了这个 Builder,就可以使用通过链式调用的方式来构建对象(建造者模式)。

import lombok.Builder;
import lombok.ToString;@Builder
@ToString
public class Customer {private String customerId;private String name;private String email;private String phoneNumber;
}

编译后的代码:

public class Customer {private String customerId;private String name;private String email;private String phoneNumber;Customer(String customerId, String name, String email, String phoneNumber) {this.customerId = customerId;this.name = name;this.email = email;this.phoneNumber = phoneNumber;}public static CustomerBuilder builder() {return new CustomerBuilder();}public String toString() {return "Customer(customerId=" + this.customerId + ", name=" + this.name + ", email=" + this.email + ", phoneNumber=" + this.phoneNumber + ")";}public static class CustomerBuilder {private String customerId;private String name;private String email;private String phoneNumber;CustomerBuilder() {}public CustomerBuilder customerId(String customerId) {this.customerId = customerId;return this;}public CustomerBuilder name(String name) {this.name = name;return this;}public CustomerBuilder email(String email) {this.email = email;return this;}public CustomerBuilder phoneNumber(String phoneNumberCu

使用 Builder 去构造 Customer 对象:

import org.junit.jupiter.api.Test;/*** @author jxd* {@code @date} 2024/3/26 22:05*/
public class UseCustomer {@Testpublic void useBuilder() {final Customer tom = new Customer.CustomerBuilder().email("example.163.com").customerId("1").phoneNumber("1121").name("tom").build();System.out.println(tom);}
}

懒加载

@Getter(lazy = true)

常见坑

boolean 类型的字段

@Data
public class Product {private String name;private double price;private String description;/*** boolean 类型的字段会生成 is 方法,而不会生成 get 方法*/private boolean sellOut;
}

编译后的代码:

public class Product {private String name;private double price;private String description;private boolean sellOut;public Product() {}public String getName() {return this.name;}public double getPrice() {return this.price;}public String getDescription() {return this.description;}public boolean isSellOut() {return this.sellOut;}public void setName(String name) {this.name = name;}public void setPrice(double price) {this.price = price;}public void setDescription(String description) {this.description = description;}public void setSellOut(boolean sellOut) {this.sellOut = sellOut;}public boolean equals(Object o) {if (o == this) {return true;} else if (!(o instanceof Product)) {return false;} else {Product other = (Product)o;if (!other.canEqual(this)) {return false;} else if (Double.compare(this.getPrice(), other.getPrice()) != 0) {return false;} else if (this.isSellOut() != other.isSellOut()) {return false;} else {label40: {Object this$name = this.getName();Object other$name = other.getName();if (this$name == null) {if (other$name == null) {break label40;}} else if (this$name.equals(other$name)) {break label40;}return false;}Object this$description = this.getDescription();Object other$description = other.getDescription();if (this$description == null) {if (other$description != null) {return false;}} else if (!this$description.equals(other$description)) {return false;}return true;}}}protected boolean canEqual(Object other) {return other instanceof Product;}public int hashCode() {int PRIME = true;int result = 1;long $price = Double.doubleToLongBits(this.getPrice());result = result * 59 + (int)($price >>> 32 ^ $price);result = result * 59 + (this.isSellOut() ? 79 : 97);Object $name = this.getName();result = result * 59 + ($name == null ? 43 : $name.hashCode());Object $description = this.getDescription();result = result * 59 + ($description == null ? 43 : $description.hashCode());return result;}public String toString() {return "Product(name=" + this.getName() + ", price=" + this.getPrice() + ", description=" + this.getDescription() + ", sellOut=" + this.isSellOut() + ")";}

sellOut 字段是 Boolean 类型,没有生成它的 get 方法,生成了一个 isSellOut 方法。

名称不规则字段的 get set 方法名问题

import lombok.Data;@Data
public class Book {private String isbn;private String title;private String aAuthor;private int pageCount;private double price;
}

编译后的代码:

public class Book {private String isbn;private String title;private String aAuthor;private int pageCount;private double price;// 省略无关代码public String getAAuthor() {return this.aAuthor;}public void setAAuthor(String aAuthor) {this.aAuthor = aAuthor;} 
}

使用 idea 生成的 get 和 set 方法却是:

public String getaAuthor() {return aAuthor;
}public void setaAuthor(String aAuthor) {this.aAuthor = aAuthor;
}

因为这个原因,导致 lombok 和 mybatis 一起使用时有时就会产生问题。

生成的 equals 方法

使用 @Data 注解生成的 equals 方法,默认只判断了当前类的属性是否相等,而忽略了父类的属性,从而使两个明显不相等的对象通过 equals 判断为相等。
解决方式就是使用 @EnqualsAndHashCode 注解并显示指定 canSuper=true,这样就会调用父类的 equals 方法。

import lombok.Data;/*** @author jxd* {@code @date} 2024/3/26 22:34*/
@Data
public class PictureBook extends Book {private Integer pictureNm;
}

上面定义了一个 PictureBook 类,使用了 @Data 注解,如果调用 PictureBook 的 equals 方法,默认只会根据 pictureNm 来判断两个 PictureBook 对象是否相等。
需要添加如下的注解,才会调用父类的 equals 方法。

相关文章:

  • YOLOV8逐步分解(2)_DetectionTrainer类初始化过程
  • 线程安全问题及解决
  • mysql--事务四大特性与隔离级别
  • Neo4j桌面版导入CVS文件
  • 利用瑞士军刀netcat建立连接并实现文件上传
  • 从姿态估计到3D动画
  • 1.7.2 python练习题15道
  • C++超市商品管理系统
  • 计算机网络基础——网络安全/ 网络通信介质
  • 大学 Python 程序设计实验报告:判断变量名是否合法
  • XSKY 智能存储,助力“数据要素 X”先进制造
  • openGauss Index-advisor_索引推荐
  • docker 的八大技术架构(图解)
  • 【Web前端】CSS基本语法规范和引入方式常见选择器用法常见元素属性
  • Android 观察者模式
  • JavaScript-如何实现克隆(clone)函数
  • 时间复杂度分析经典问题——最大子序列和
  • [Vue CLI 3] 配置解析之 css.extract
  • Centos6.8 使用rpm安装mysql5.7
  • CSS中外联样式表代表的含义
  • JavaScript类型识别
  • Java方法详解
  • Objective-C 中关联引用的概念
  • Shadow DOM 内部构造及如何构建独立组件
  • Vue组件定义
  • 飞驰在Mesos的涡轮引擎上
  • 计算机在识别图像时“看到”了什么?
  • 简析gRPC client 连接管理
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 收藏好这篇,别再只说“数据劫持”了
  • 硬币翻转问题,区间操作
  • 与 ConTeXt MkIV 官方文档的接驳
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 【云吞铺子】性能抖动剖析(二)
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • C# - 为值类型重定义相等性
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (+4)2.2UML建模图
  • (26)4.7 字符函数和字符串函数
  • (C++17) std算法之执行策略 execution
  • (二)构建dubbo分布式平台-平台功能导图
  • (二开)Flink 修改源码拓展 SQL 语法
  • (三)c52学习之旅-点亮LED灯
  • (译)2019年前端性能优化清单 — 下篇
  • .NET 读取 JSON格式的数据
  • .net 反编译_.net反编译的相关问题
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .net下简单快捷的数值高低位切换
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @Valid和@NotNull字段校验使用
  • [AX]AX2012 R2 出差申请和支出报告