Lombok 注解

Lombok 是一个 Java 库,通过注解自动生成样板代码,让代码更简洁。

解决的问题

传统 Java 开发中,需要手写大量重复代码:

没有 Lombok:

public class User {
    private Long id;
    private String name;
    private Integer age;
    
    // 需要手写 100+ 行代码:
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    
    @Override
    public String toString() { ... }
    
    @Override
    public boolean equals(Object o) { ... }
    
    @Override
    public int hashCode() { ... }
    
    public User() {}
    public User(Long id, String name, Integer age) { ... }
}

使用 Lombok:

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
}
// 仅 10 行代码,功能完全相同!

主要功能

功能注解作用
getter/setter@Getter @Setter自动生成访问器
构造器@NoArgsConstructor @AllArgsConstructor自动生成构造方法
通用方法@ToString @EqualsAndHashCode自动生成常用方法
一站式@Data包含上述所有功能
建造者模式@Builder优雅的对象创建
日志@Slf4j自动注入日志对象
链式调用@Accessors(chain=true)支持流式编程

工作原理

编译时处理
Java 源码 → Lombok 处理器 → 生成字节码 → 最终 .class 文件
  • 编译时生成代码,不是反射
  • 零运行时开销
  • IDE 完全支持(需安装插件)

核心优势

  1. 代码量减少 60%-80% 📉
  2. 提高可读性 - 关注业务逻辑而非样板代码
  3. 减少出错 - 自动生成的代码不会写错
  4. 易于维护 - 修改字段时无需手动更新 getter/setter

典型应用场景

  • POJO/DTO 类 - 数据传输对象
  • 实体类 - 数据库映射
  • 配置类 - 配置属性绑定
  • Service 层 - 使用 @Slf4j 记录日志

一句话总结

Lombok = 用注解消灭 Java 样板代码的神器! 告别手写 getter/setter/toString 的痛苦,专注于真正重要的业务逻辑。

一、数据类相关注解

1. @Data

作用: 一站式注解,包含以下功能的组合

  • 生成所有字段的 getter 方法
  • 生成所有非 final 字段的 setter 方法
  • 生成 toString() 方法
  • 生成 equals() 和 hashCode() 方法
  • 生成一个包含所有 final 字段的构造器

示例:

import lombok.Data;

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
}

// 相当于手写了:
// - getId(), setId()
// - getName(), setName()
// - getAge(), setAge()
// - toString()
// - equals() 和 hashCode()

2. @Getter

作用: 为类的所有字段生成 getter 方法

示例:

import lombok.Getter;

@Getter
public class User {
    private String name;
    private Integer age;
}

// 自动生成:
// public String getName() { return name; }
// public Integer getAge() { return age; }

字段级别使用:

public class User {
    @Getter
    private String name;  // 只为 name 生成 getter
    
    private String password;  // 不生成 getter
}

3. @Setter

作用: 为类的所有非 final 字段生成 setter 方法

示例:

import lombok.Setter;

@Setter
public class User {
    private String name;
    private Integer age;
}

// 自动生成:
// public void setName(String name) { this.name = name; }
// public void setAge(Integer age) { this.age = age; }

4. @ToString

作用: 生成 toString() 方法

示例:

import lombok.ToString;

@ToString
public class User {
    private String name;
    private Integer age;
}

// 输出: User(name=张三, age=18)

常用参数:

// 排除某些字段
@ToString(exclude = {"password", "token"})

// 只包含某些字段
@ToString(of = {"id", "name"})

// 调用父类的 toString
@ToString(callSuper = true)

5. @EqualsAndHashCode

作用: 生成 equals() 和 hashCode() 方法

示例:

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class User {
    private Long id;
    private String name;
}

常用参数:

// 排除某些字段
@EqualsAndHashCode(exclude = {"updateTime"})

// 只使用某些字段
@EqualsAndHashCode(of = {"id"})

// 调用父类的方法
@EqualsAndHashCode(callSuper = true)

二、构造器相关注解

6. @NoArgsConstructor

作用: 生成无参构造器

示例:

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class User {
    private String name;
    private Integer age;
}

// 生成: public User() {}

常用参数:

// 强制生成(即使有 final 字段)
@NoArgsConstructor(force = true)

// 设置访问级别
@NoArgsConstructor(access = AccessLevel.PRIVATE)

7. @AllArgsConstructor

作用: 生成包含所有字段的构造器

示例:

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class User {
    private String name;
    private Integer age;
}

// 生成: public User(String name, Integer age) { ... }

8. @RequiredArgsConstructor

作用: 为所有 final 字段和 @NonNull 字段生成构造器

示例:

import lombok.RequiredArgsConstructor;
import lombok.NonNull;

@RequiredArgsConstructor
public class User {
    private final Long id;        // 必须在构造器中初始化
    @NonNull 
    private String name;          // 必须在构造器中初始化
    private Integer age;          // 不在构造器中
}

// 生成: public User(Long id, String name) { ... }

三、链式调用相关注解

9. @Accessors

作用: 控制 getter/setter 的生成方式

示例:

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)  // 链式调用
public class User {
    private String name;
    private Integer age;
}

// 使用
User user = new User()
    .setName("张三")
    .setAge(18);

常用参数:

// 链式调用(setter 返回 this)
@Accessors(chain = true)

// 流式风格(去掉 set 前缀)
@Accessors(fluent = true)
// 使用: user.name("张三").age(18)

// 字段前缀(自动去除前缀)
@Accessors(prefix = "m")
private String mName;  // getter 是 getName() 而不是 getMName()

四、建造者模式注解

10. @Builder

作用: 生成建造者模式代码

示例:

import lombok.Builder;

@Builder
public class User {
    private Long id;
    private String name;
    private Integer age;
}

// 使用
User user = User.builder()
    .id(1L)
    .name("张三")
    .age(18)
    .build();

与 @Data 结合:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor  // @Builder 需要全参构造器
public class User {
    private String name;
    private Integer age;
}

默认值:

@Builder
public class User {
    @Builder.Default
    private Integer status = 1;  // 设置默认值
}

五、日志相关注解

11. @Slf4j

作用: 自动生成 SLF4J 日志对象

示例:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserService {
    public void test() {
        log.info("这是日志");
        log.error("错误信息", exception);
    }
}

// 相当于手写:
// private static final Logger log = LoggerFactory.getLogger(UserService.class);

其他日志注解:

@Log          // java.util.logging.Logger
@Log4j        // Log4j
@Log4j2       // Log4j2
@CommonsLog   // Apache Commons Logging

六、空值检查注解

12. @NonNull

作用: 自动生成空值检查代码

示例:

import lombok.NonNull;

public class User {
    public void setName(@NonNull String name) {
        this.name = name;
    }
}

// 自动生成:
// public void setName(String name) {
//     if (name == null) {
//         throw new NullPointerException("name is marked non-null but is null");
//     }
//     this.name = name;
// }

七、资源清理注解

13. @Cleanup

作用: 自动调用资源的 close() 方法

示例:

import lombok.Cleanup;

public void readFile() throws IOException {
    @Cleanup 
    InputStream in = new FileInputStream("file.txt");
    // 会自动调用 in.close()
}

// 相当于 try-with-resources

八、异常处理注解

14. @SneakyThrows

作用: 自动捕获并抛出受检异常(不推荐滥用)

示例:

import lombok.SneakyThrows;

@SneakyThrows
public void readFile() {
    // 不需要 try-catch 或 throws IOException
    FileInputStream in = new FileInputStream("file.txt");
}

九、同步锁注解

15. @Synchronized

作用: 自动生成同步代码块

示例:

import lombok.Synchronized;

public class Counter {
    private final Object lock = new Object();
    
    @Synchronized
    public void increment() {
        // 线程安全
    }
    
    @Synchronized("lock")
    public void decrement() {
        // 使用指定的锁对象
    }
}

十、其他实用注解

16. @Value

作用: 不可变类的简化写法(所有字段 final + private)

示例:

import lombok.Value;

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

// 相当于:
// - 所有字段 private final
// - 生成 getter(没有 setter)
// - 生成全参构造器
// - 生成 toString, equals, hashCode

17. @With

作用: 生成 withXxx() 方法,返回修改后的新对象(不可变)

示例:

import lombok.Value;
import lombok.With;

@Value
@With
public class User {
    String name;
    Integer age;
}

// 使用
User user1 = new User("张三", 18);
User user2 = user1.withAge(20);  // 返回新对象,user1 不变

18. @UtilityClass

作用: 工具类(私有构造器 + 所有方法静态)

示例:

import lombok.experimental.UtilityClass;

@UtilityClass
public class StringUtils {
    public String reverse(String str) {
        return new StringBuilder(str).reverse().toString();
    }
}

// 自动添加私有构造器,防止实例化

19. @FieldDefaults

作用: 统一设置字段的访问级别和是否 final

示例:

import lombok.experimental.FieldDefaults;
import lombok.AccessLevel;

@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class User {
    Long id;      // 自动变为 private final
    String name;  // 自动变为 private final
}

📋 常用组合推荐

1. 普通 POJO 类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User { ... }

2. 实体类(支持链式调用)

@Data
@Accessors(chain = true)
public class User { ... }

3. 建造者模式

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User { ... }

4. 不可变对象

@Value
@Builder
public class User { ... }

5. Service 层

@Slf4j
@Service
public class UserService { ... }

⚠️ 注意事项

  1. @Data 的陷阱: 在 JPA 实体类中慎用,可能导致循环引用
  2. @Builder 需要全参构造器: 要配合 @AllArgsConstructor 使用
  3. 继承问题: 子类使用 @ToString@EqualsAndHashCode 时记得加 callSuper = true
  4. 性能: Lombok 是编译时生成代码,运行时无性能损耗
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐