1. 概览
Java 是一种很好的语言,但在我们的代码中完成一些常见任务或遵守某些框架规范时,有时会显得过于冗长。
这通常不会为我们的程序业务方面带来任何实际价值,而 Lombok 则可以帮助我们提高生产效率。
它通过嵌入到我们的构建过程中,并根据我们在代码中引入的一些项目注解,自动生成 Java 字节码到我们的.class 文件中。
我们可以将 Project Lombok 的 Java 库插入到构建工具中,以自动化一些代码,例如 getter/setter 方法和日志变量。
在本教程中,我们将讨论如何使用 Lombok 与 Maven 来利用一些这些功能。
2. Maven 项目配置
将 Project Lombok 包含在我们的构建中,无论我们使用的是哪种系统,都非常简单。Project Lombok 的项目页面上有详细的说明。我们可以将 Maven Lombok 依赖项放在提供的范围中:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<scope>provided</scope>
</dependency>
依赖 Lombok 不会让我们的.jar 文件的用户也依赖它,因为 Lombok 只是一个纯构建依赖,不是运行时依赖。
3. 最终局部变量的类型推断
截至 Lombok 1.16.20 版本,Lombok 支持使用 var 从初始化表达式推断局部变量的类型。在 Lombok 1.18.22 版本中,支持使用 val 进行最终局部变量类型的推断。换句话说,Lombok 将 val 替换为 final var。然而,我们不能在字段上使用此功能。
让我们通过一个例子来演示 Lombok 局部变量的类型推断:
public String lombokTypeInferred() {
val list = new ArrayList<String>();
list.add("Hello, Lombok!");
val listElem = list.get(0);
return listElem.toLowerCase();
}
自动代码生成使 list 成为一个 final 类型的 ArrayList<String>变量。
4. 获取/设置方法、构造函数
通过公共 getter 和 setter 方法封装对象属性是 Java 中的常见做法,许多框架广泛依赖于这种"JavaBean"模式(一个带有空构造函数且包含用于"属性"的 get/set 方法的类)。
这在大多数情况下非常常见,大多数 IDE 都支持自动生成这些模式的代码(以及其他更多代码)。然而,这些代码需要存在于我们的源码中,并且当添加新属性或重命名字段时需要进行维护。
让我们考虑一下我们要用作 JPA 实体的这个类:
@Entity
public class User implements Serializable {
private @Id Long id; // will be set when persisting
private String firstName;
private String lastName;
private int age;
public User() {}
public User(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
// getters and setters: ~30 extra lines of code
}
这是一个相当简单的类,但如果我们添加了 Getter 和 Setter 的额外代码,最终定义中将包含比相关业务信息更多的样板零值代码:"一个 User 具有名字和姓氏以及年龄。"
现在让我们使用 Lombok 来简化这个类:
@Entity
@Getter @Setter @NoArgsConstructor // <--- THIS is it
public class User implements Serializable {
private @Id Long id; // will be set when persisting
private String firstName;
private String lastName;
private int age;
public User(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
}
通过添加@Getter 和@Setter 注解,我们告诉 Lombok 为所有类字段生成这些方法。@NoArgsConstructor 将导致生成一个空构造函数。
请注意,这是一整段类代码;与上面带有// 获取器和设置器注释的版本不同,我们没有省略任何内容。对于一个具有三个相关属性的类来说,这可是显著节省了代码量!
如果我们为 User 类添加属性(字段),同样的情况也会发生;我们将注解应用到类型本身,这样它们会默认处理所有字段。
如果我们想细化某些属性的可见性,例如,如果希望保持实体类的 id 字段修饰符为包私有或受保护,因为它们预期只读取但不会由应用程序代码显式设置,我们只需为此特定字段使用更精细粒度的@Setter 注解:
private @Id @Setter(AccessLevel.PROTECTED) Long id;