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

2、Lombok核心注解详解:@Getter、@Setter、@Data 等基础注解全面解析

学习目标:掌握 Lombok 最常用的 8 个核心注解,理解它们如何简化 POJO 编写,知道每个注解的生成效果、参数配置和适用场景。


1. 为什么需要这些注解?

在 Java 开发中,数据类(POJO/DTO/VO/Entity)通常需要以下方法:

  • Getter/Setter:访问和修改字段
  • toString():调试和日志输出
  • equals() / hashCode():集合操作、去重、缓存键
  • 构造器:对象初始化
  • 日志对象:记录运行信息

手动编写这些方法不仅繁琐,还容易出错。Lombok 通过注解一键生成,让我们专注业务字段定义。


2. POJO 简化“四件套”

2.1 @Getter 和 @Setter

基本用法
import lombok.Getter;
import lombok.Setter;@Getter
@Setter
public class Product {private Long id;private String name;private Double price;
}

生成效果

  • 为每个非静态字段生成 public 的 getter 和 setter 方法
  • boolean 字段的 getter 以 is 开头(如 isActive()
// 实际生成的代码(反编译后)
public Long getId() { return this.id; }
public void setId(Long id) { this.id = id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
// ... 其他字段类似
精细控制

你可以控制访问级别和排除字段:

@Getter(AccessLevel.PROTECTED)  // getter 为 protected
@Setter(AccessLevel.NONE)       // 禁用所有 setter
public class User {private String username;@Setter(AccessLevel.PRIVATE) // 单独为字段设置private String password;@Getter(AccessLevel.NONE)    // 不生成 getterprivate String secretKey;
}

AccessLevel 可选值PUBLIC(默认)、PROTECTEDPACKAGEPRIVATENONE

使用场景
  • ✅ 大多数 POJO/DTO/VO/Entity 类
  • ❌ 不适用于需要自定义逻辑的 setter(如参数校验)

2.2 @ToString

基本用法
@ToString
public class Order {private Long id;private String customerName;private Double amount;
}

生成效果

@Override
public String toString() {return "Order(id=" + this.id + ", customerName=" + this.customerName + ", amount=" + this.amount + ")";
}
常用参数
@ToString(includeFieldNames = true,   // 包含字段名(默认 true)callSuper = false,          // 是否调用父类 toString()(默认 false)exclude = {"password"},     // 排除敏感字段of = {"id", "name"}         // 只包含指定字段(优先级高于 exclude)
)
public class User {private Long id;private String name;private String password;    // 不会出现在 toString 中
}

💡 安全提示:永远不要在 toString() 中输出密码、密钥等敏感信息!

使用场景
  • ✅ 所有需要日志输出或调试的类
  • ✅ API 响应对象(便于排查问题)

2.3 @EqualsAndHashCode

基本用法
@EqualsAndHashCode
public class Book {private String isbn;private String title;
}

生成效果

  • 基于所有非静态、非 transient 字段生成 equals()hashCode()
  • 遵循 Java 规范:相等对象必须有相同 hashCode
@Override
public boolean equals(Object o) {if (o == this) return true;if (!(o instanceof Book)) return false;Book other = (Book) o;if (!other.canEqual(this)) return false;final Object this$isbn = this.isbn;final Object other$isbn = other.isbn;if (this$isbn == null ? other$isbn != null : !this$isbn.equals(other$isbn)) return false;// ... 其他字段比较return true;
}@Override
public int hashCode() {final int PRIME = 59;int result = 1;result = result * PRIME + (this.isbn == null ? 43 : this.isbn.hashCode());// ... 其他字段return result;
}
重要参数
@EqualsAndHashCode(callSuper = false,          // 是否包含父类字段(默认 false)exclude = {"createTime"},   // 排除字段of = {"id"}                 // 只基于 id 判断相等性
)
public class Article {private Long id;private String title;private LocalDateTime createTime; // 不参与 equals/hashCode
}

⚠️ 继承警告:如果类有子类,建议设置 callSuper = true,否则可能违反 equals 对称性。

使用场景
  • ✅ 存储在 HashSetHashMap 中的对象
  • ✅ 需要去重的业务场景
  • ❌ 不适用于包含循环引用的对象(可能导致 StackOverflow)

3. 组合注解:事半功倍

3.1 @Data(最常用!)

@Data 是 Lombok 的“瑞士军刀”,组合了多个注解

// @Data 等价于以下注解的组合:
@Getter
@Setter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
使用示例
@Data
public class Student {private Long id;private String name;private Integer age;
}

自动生成

  • 所有字段的 getter/setter
  • toString() 方法
  • equals() 和 hashCode()
  • @RequiredArgsConstructor:为所有 final 字段和 @NonNull 字段生成构造器
注意事项
  • 不会生成无参构造器!如果需要,需额外添加 @NoArgsConstructor
  • 谨慎用于 JPA Entity:某些框架要求无参构造器
使用场景
  • ✅ DTO(数据传输对象)
  • ✅ VO(视图对象)
  • ✅ 简单的配置类
  • ❌ 复杂的业务实体(可能需要自定义 equals/hashCode 逻辑)

3.2 @Value(不可变对象)

@Value 用于创建不可变类(Immutable Class):

@Value
public class Point {private final int x;private final int y;
}

生成效果

  • 所有字段自动变为 private final
  • 只生成 getter(无 setter)
  • 生成全参构造器
  • 生成 toString、equals、hashCode

等价于:

// 手动编写需要这么多代码!
public final class Point {private final int x;private final int y;public Point(int x, int y) {this.x = x;this.y = y;}public int getX() { return x; }public int getY() { return y; }@Overridepublic boolean equals(Object o) { /* ... */ }@Overridepublic int hashCode() { /* ... */ }@Overridepublic String toString() { /* ... */ }
}
使用场景
  • ✅ 配置项(如数据库连接信息)
  • ✅ 函数式编程中的值对象
  • ✅ 多线程安全的数据载体

4. 构造器注解:灵活初始化

4.1 @NoArgsConstructor

生成无参构造器

@NoArgsConstructor
public class User {private String name;private Integer age;
}// 生成:public User() {}

重要:JPA、Jackson 等框架通常要求实体类有无参构造器。


4.2 @AllArgsConstructor

生成全参构造器(包含所有字段):

@AllArgsConstructor
public class Product {private Long id;private String name;private Double price;
}// 生成:public Product(Long id, String name, Double price) { ... }

4.3 @RequiredArgsConstructor

生成必需字段构造器

  • 所有 final 字段
  • 所有标记 @NonNull 的字段
@RequiredArgsConstructor
public class UserService {private final UserRepository userRepository; // final 字段@NonNullprivate String defaultRole; // @NonNull 字段
}// 生成:public UserService(UserRepository userRepository, String defaultRole) { ... }

💡 Spring 推荐用法:配合 @RequiredArgsConstructor 实现构造器注入,替代 @Autowired


4.4 构造器组合使用

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {private Long id;private String customerName;private Double amount;
}

这样既支持无参构造(框架需要),也支持全参构造(测试或 Builder 模式)。


5. 日志注解:告别手动声明

5.1 @Slf4j(最常用)

自动生成 SLF4J 日志实例:

@Slf4j
public class OrderService {public void processOrder(Order order) {log.info("Processing order: {}", order.getId());log.debug("Order details: {}", order);}
}// 等价于手动编写:
// private static final Logger log = LoggerFactory.getLogger(OrderService.class);

5.2 其他日志框架支持

注解对应框架
@Logjava.util.logging
@Log4jLog4j 1.x
@Log4j2Log4j 2.x
@CommonsLogApache Commons Logging
@JBossLogJBoss Logging

推荐:使用 @Slf4j,它是日志门面,便于切换底层实现。


6. 注解使用对比表

注解生成内容典型场景注意事项
@Getter/@Settergetter/setter 方法通用 POJO可控制访问级别
@ToStringtoString() 方法调试、日志排除敏感字段
@EqualsAndHashCodeequals()/hashCode()集合操作继承时注意 callSuper
@Data以上全部 + RequiredArgsConstructorDTO、VO不生成无参构造器
@Value不可变类全套方法配置、值对象字段自动 final
@NoArgsConstructor无参构造器JPA Entity、Jackson框架集成必需
@AllArgsConstructor全参构造器测试、Builder字段顺序敏感
@Slf4j日志实例所有服务类推荐 SLF4J

7. 实战示例:完整用户类

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.ToString;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;// 组合使用:DTO 场景
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(exclude = "password") // 安全:不打印密码
@EqualsAndHashCode(exclude = "lastLoginTime") // 登录时间不影响用户相等性
@Slf4j
public class UserDTO {private Long id;private String username;private String password; // 敏感字段private String email;private LocalDateTime lastLoginTime;public static void main(String[] args) {UserDTO user = new UserDTO(1L, "john", "secret", "john@example.com", null);log.info("Created user: {}", user); // 不会泄露密码}
}

8. 小结

你已掌握

  • 四件套注解@Getter/@Setter/@ToString/@EqualsAndHashCode 的精细控制
  • 组合注解@Data(万能)和 @Value(不可变)的适用场景
  • 构造器注解:三种构造器的生成规则和组合使用
  • 日志注解@Slf4j 快速集成日志

➡️ 下一步:进入 03-Lombok进阶功能实战,学习 @Builder@SneakyThrows 等高级功能!

💡 最佳实践提醒

  • 优先使用 @Data + @NoArgsConstructor 组合
  • 敏感字段务必在 @ToString 中排除
  • Entity 类慎用 @Data,建议手动控制 equals/hashCode 逻辑
http://www.dtcms.com/a/418150.html

相关文章:

  • 兴力网站建设wordpress文章类型模板
  • springboot高校教务管理系统设计与实现(代码+数据库+LW)
  • Vala 编程语言高级特性-具有语法支持的方法
  • JavaEE初阶4.0
  • 医疗编程AI技能树与培训技能树报告(国内外一流大学医疗AI相关专业分析2025版,上)
  • 【IEEE出版 | 高录用、稳定检索】第七届信息与计算机前沿技术国际学术会议(ICFTIC 2025)
  • 我爱学算法之—— 模拟(上)
  • 白云做网站网店怎么注册开网店
  • 有了域名和主机怎么做网站erp软件是什么软件
  • 大数据毕业设计选题推荐-基于大数据的青光眼数据可视化分析系统-大数据-Spark-Hadoop-Bigdata
  • 数据可视化 | 热力图Heatmap绘制Python代码 相关性矩阵学术可视化
  • C#对称加密(AES)的简单代码
  • AR眼镜在安防领域人脸识别技术方案|阿法龙XR云平台
  • 【传奇开心果系列】基于Flet实现的第三次大的升级优化版语音播报成语接龙小游戏V3.0.1特色和实现原理深度解析
  • 【Qt】输入类控件2——SpinBox,DateEdit,TimeEdit,Dial,Slider
  • activemq延迟消息变成实时收到了?
  • 重庆市住房和城乡建设部网站中山人才招聘网官网
  • 如何构建有效的需求知识库?如何让你的AI用它来评审新需求?
  • HTML 和 Streamlit ,到底哪个好
  • 数据结构 之 【图的遍历与最小生成树】(广度优先遍历算法、深度优先遍历算法、Kruskal算法、Prim算法实现)
  • 胶州做网站的做网站设计有哪些网页
  • 开源 C# 快速开发(十)通讯--http客户端
  • 如何用 ShedLock 让 Spring Boot 的定时任务在多实例环境下只执行一次
  • Mask R-CNN工业落地实战:计算机视觉物体检测开山鼻祖的产线级代码剖析
  • 沈阳网站制作全网性做橡胶的网站
  • C++压缩解压:Zstandard (Zstd)压缩库
  • 在网站建设中 为了防止工期拖延荥阳网站制作
  • Filebeat写ElasticSearch故障排查思路(下)
  • 禅道数据还原
  • 货架 网站建设 牛商网网站设计目的与规划怎么写