LomBok快速入门使用

376 阅读8分钟

Project Lombok 是一个 java 库,可自动插入您的编辑器和构建工具,为您的 java 增添趣味。 永远不要再编写另一个 getter 或 equals 方法,使用一个注释,您的类就有一个功能齐全的构建器、自动化您的日志记录变量等等。(官网直译)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

官网地址:

projectlombok.org/

maven包:

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

val

你可以使用 val 声明本地变量的类型而不用写出它的实际类型,它实际的类型将由初始化的表达式推断。局部变量将被声明为 final 。这个功能只在局部变量和foreach循环中奏效,在字段中不奏效。并且初始化表达式是必须的。

val 实际上是实际的类型,它是一个真实的类并可以在 Lombok 的包中找到,你使用 val 前必须先导包。

carbon (2).png

@NonNull

这个注解可放在参数、方法、构造函数上,它将为你生成一个null检查。

空检查:if (param == null) throw new NullPointerException("param is marked non-null but is null");

@Cleanup

使用@Cleanup来确保代码执行路径退出当前作用域之前自动清除给定资源 如下:

@Cleanup InputStream in = new FileInputStream("some/file");

在末尾将会调用in.close()。保证通过try/fianlly构造运行次此调用

若你要清理的对象类型没有close()方法,但有其他无参数的方法,则可以指定此方法的名称如下:

@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);

@Getter and @Setter

自动生成getter/setter

@ToString

实现toString()方法

如果您想跳过某些字段,可以使用 注释这些字段@ToString.Exclude。或者,您可以使用 准确指定您希望使用的@ToString(onlyExplicitlyIncluded = true)字段,然后用 标记您要包含的每个字段@ToString.Include

您可以更改用于标识成员的名称@ToString.Include(name = "some other name"),并且可以更改成员的打印顺序@ToString.Include(rank = -1)。没有等级的成员被认为具有等级 0,首先打印更高等级的成员,并且相同等级的成员按照它们在源文件中出现的顺序打印。

@EqualsAndHashCode

自动生成equals(Object other)hashCode()方法的实现

在 lombok 1.16.22 之前,可以使用注释的ofexclude参数完成包含/排除。@EqualsAndHashCode这种旧式包含机制仍然受支持,但将来会被弃用。

排除某个参数@EqualsAndHashCode.Exclude

@NoArgsConstructor、@RequiredArgsConstructor、@AllArgsConstructor

这组3注释生成一个构造函数。

@NoArgsConstructor将生成一个没有参数的构造函数。

使用final字段会导致变异错误 加上 force=true则不会报错,此注释主要与@NonNull 和@Data结合使用 @RequiredArgsConstructor为每个需要特殊处理的字段生成一个带有 1 个参数的构造函数

构造对加@NonNull和final修饰的参数 生成的构造方法是private,如果想对外提供可以使用 @RequiredArgsConstructor(staticName="of") 与普通的构造函数不同,这样的静态工厂方法将推断泛型

@AllArgsConstructor为类中的每个字段生成一个带有 1 个参数的构造函数。标有的字段会@NonNull导致对这些参数进行空检查。

所有参数进行构造 access @AllArgsConstructor(access = AccessLevel.PRIVATE)构造函数 权限 如果所有的类都加有 final 和@NonNull注解 会报编译错误 已在类中定义了构造器 AllArgsConstructor 和 RequiredArgsConstructor 冲突

这三者可以同时出现 也可以加自己编写的专门的构造器 若出现冲突(专门的构造器和lombok生成的签名一致) 会引发编译错误

@Data

相当于@ToString,@EqualsAndHashCode,@Getter/@Setter ,@RequiredArgsConstructor合集所有生成的getter和setter都是public,如果要覆盖访问级别 需要显示@Setter和@Getter注释字段或类。

@Value

使不可变类变的非常容易。

不可变类时指创建该类的实例后,该实例的实例变量是不可改变的。

不可变类遵循以下规则:

  • 使用private和final修饰符来修饰该类的成员变量;

  • 提供带参数的构造器,根据传入的参数来初始化类里的成员变量;

  • 仅为该类的成员变量提供getter方法,不要提供setter方法,因为普通方法无法修改final修饰的成员变量;

  • 如果有必要,重写Object类的hascode()和equals()方法。equals方法根据关键成员变量来作为两个对象是否相等的标准,除此之外,还应该保证两个用equals方法判断为相等的对象的hashCode()也相等。如果有必要,重写Object类的hascode()和equals()方法。equals方法根据关键成员变量来作为两个对象是否相等的标准,除此之外,还应该保证两个用equals方法判断为相等的对象的hashCode()也相等。

请注意,如果 @Builder@Value 都在一个类上,则 @Builder 想要创建的私有构造 函数“胜过” @Value 想要创建的公共构造函数。

@Builder

为类生成复杂的构建器API 如图:

carbon (4).png

可以放在构造函数或方法上@Builder内部做了:

1.创建一个名为ThisClassBuilder的内部静态类,并具有和实体类形同的属性(构建器)。

2.在构建器中:对于目标类中的所有属性和未初始化的final字段,都会在构建器中创建对应属性。

3.在构建器中:创建一个无参default构造函数。

4.在构造其中:对于实体类中的每个参数,都会对应创建类似于setter的方法,只不过方法名与该参数名相同。并且返回值是构建器本身。

5.在构建器中:一个build()方法,调用此方法,就会根据设置的值来创建实体对象。

6.在实体类中:会穿件一个builder()方法,它的目的是用来创建构建器的。

在@Builder中使用@Singular注释集合

@Builder​​也可以为集合类型的参数或字段生成一种特殊的方法。 它采用修改列表中一个元素而不是整个列表的方式,可以是增加一个元素,也可以是删除一个元素。

carbon (5).png@Singular​​只能应用于​​lombok​​已知的集合类型。目前,支持的类型有: java.util: ​​Iterable​​, ​​Collection​​, 和​​List​​ (一般情况下,由压缩的不可修改的​​ArrayList​​支持). ​​Set​​, ​​SortedSet​​, and ​​NavigableSet​​ (一般情况下,生成可变大小不可修改的​​HashSet​​或者​​TreeSet​​). ​​Map​​, ​​SortedMap​​, and ​​NavigableMap​​ (一般情况下,生成可变大小不可修改的​​HashMap​​或者​​TreeMap​​). Guava’s com.google.common.collect: ​​ImmutableCollection​​ and ​​ImmutableList​​ ​​ImmutableSet​​ and ​​ImmutableSortedSet​​ ​​ImmutableMap​​, ​​ImmutableBiMap​​, and ​​ImmutableSortedMap​​ ​​ImmutableTable​​

@SneakyThrows

可以用来偷偷抛出检查异常,而无需在方法的throws字句中实际声明它。

Thread.sleep(122);经常要抛出异常或者声明异常 在方法上加上@SneakyThrows即可 编译后是try{}catch{}

@Synchronized

@Synchronizedsynchronized方法修饰符的一个更安全的变体。

注解只能在静态方法和实例方法上使用。它的操作类似于synchronized关键字,但是它锁定在不同的对象上。关键字锁定在上this,但注释锁定在名为的字段上$ lock,该字段是私有的。 如果该字段不存在,则会为您创建。如果对static方法进行注释,则注释将锁定在名为的静态字段上$ LOCK。

@With

如果您创建公共类Point {private final int x,y; },setter没有意义,因为这些字段是最终字段。 @With可以为您生成一个withX(int newXValue)方法,该方法将返回一个新点,该点具有x的提供值和y的相同值。

就像@Setter,您可以指定访问级别,以防您希望生成的 with 方法不是public: @With(level = AccessLevel.PROTECTED)。同样@Setter,您还可以@With在类型上添加注释,这意味着with为每个字段(甚至是非最终字段)生成一个方法。

carbon (6).png

反编译后的:

carbon (7).png

@Getter(lazy=true)

该标注用于生成一个 lazy 版的 getter,它会在第一次调用这个 getter 时计算一次值,然后从那里开始缓存它。如果计算该值需要大量 CPU,或者该值占用大量内存,这可能很有用。

注意:Lombok 会自动去管理线程安全的问题,所以不会存在重复赋值的问题。

要使用此功能,需要创建一个 private final 变量,并且使用运行成本高的表达式对其进行初始化,同时使用 @Getter(lazy=true) 注解进行标注。

@Log (and friends)

您将@Log的变体放在类中(以适用于您使用的日志系统的为准);然后,您有一个静态的final log字段,按照您使用的日志框架通常规定的方式进行初始化,然后您可以使用它来编写日志语句。

carbon (8).png

java写法

carbon (10).png

还有一些实验性的这里不做描述

一些缺点:

必须所有人下载lombok插件  可读性不高  调试性降低(某个类中的属性的getter方法被哪些类引用了)

对升级不友好 破坏封装性  

优点:

lazy==true。 参看文档 lombok官网projectlombok.org/