Lombok是一个Java包,可以通过注解的形式自动生成代码。通过使用lombok可以减少程序中许多样板代码,使程序更加清晰。
由于项目中大量使用了lombok,在此对常用的一些lombok注解做记录。
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>
@NonNull
注解作用于函数参数上,自动生成检查参数是否为null
的代码。
如代码:
public void runJob(@NonNull Job job) {
job.run();
}
形同于
public void runJob(Job job) {
if (job == null) {
throw new NullPointerException("job is marked non-null but is null");
}
job.run();
}
@Getter
和@Setter
注解作用于类的字段上,为字段自动生成getter
和setter
方法。通过AccessLevel
控制生成方法的访问权限,包括NONE
(不生成方法),PUBLIC
, PROTECTED
, PACKAGE
,MODULE
和PRIVATE
。
如代码:
class Test {
@Getter
@Setter(AccessLevel.PROTECTED)
private int field = 0;
@Getter
@Setter
private boolean ok = false;
}
形同于
class Test {
private int field = 0;
private boolean ok = false;
// 默认生成的方法是get + fieldName
public int getField() {
return field;
}
protected void setField(int field) {
this.field = field;
}
// 如果字段是boolean类型,生成的方法是is + fieldName
public boolean isOk() {
return ok;
}
public void setOk(boolean ok) {
this.ok = ok;
}
}
@Getter
和@Setter
注解也可以直接作用于类上,此时为所有non-static
字段自动生成getter
和setter
方法。字段上的@Getter
和@Setter
可以覆盖类的方法。
如代码:
@Getter
@Setter
class Test {
private int field = 0;
@Setter(AccessLevel.NONE) private boolean ok = false;
}
为所有字段生成getter
和setter
方法,但不为ok
字段生成Setter
方法。
生成一个延迟计算的getter
方法。有些字段初始化需要大量计算过程,通过此注解可以延迟该计算,仅在第一次调用getter
方法的时候计算一次。生成的getter
方法是线程安全的。
代码如下:
import lombok.Getter;
class Test {
@Getter(lazy = true)
private final long fib30 = fib(30);
public long fib(int n) {
if (n <= 0) {
return 0;
}
if (n <= 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
}
为类生成toString
方法。
代码如下:
import lombok.Setter;
import lombok.ToString;
@ToString
@Setter
class Parent {
private int age;
}
@ToString(callSuper = true)
@Setter
class Child extends Parent {
private String name;
public static void main(String[] args) {
Child child = new Child();
child.setName("child");
child.setAge(20);
System.out.println(child);
}
}
输出为:
Child(super=Parent(age=20), name=child)
注意事项:在子类中使用@ToString
注解时,需要加上callSuper = true
,否则生成的代码只包含子类的字段,而不包含父类的内容。
@EqualsAndHashCode
作用于类上,为类生成equals
和hashCode
方法。
如代码:
class Parent {
private int age;
}
@EqualsAndHashCode(callSuper = true)
class Child extends Parent {
@EqualsAndHashCode.Exclude
private String internal;
private String name;
}
注意事项:注解默认使用所有字段生成equals
和hashCode
方法。
添加callSuper = true
,让子类生成的方法中包含对父类的equals
和hashCode
方法的调用。
使用@EqualsAndHashCode.Exclude
注解让生成方法中不包含某字段。
@NoArgsConstructor
生成无参构造方法。
@RequiredArgsConstructor
生成有参构造方法,所有未初始化的final
字段,以及未初始化的被标注为@NonNull
的字段。
代码:
@RequiredArgsConstructor
class Test {
private final String name;
@NonNull
private Integer age;
private int size;
public static void main(String[] args) {
Test test = new Test("Hello", 20);
System.out.println(test);
}
}
被标注为final
和@NonNull
的字段放到了生成的有参构造方法。
@AllArgsConstructor
生成所有字段的构造方法。
三个注解都有staticName = "of"
参数,可以生成private
的构造函数,并使用静态方法of
暴露出去。
代码如下:
@AllArgsConstructor(staticName = "of")
class Test {
private final String name;
@NonNull
private Integer age;
private int size;
public static void main(String[] args) {
Test test = Test.of("Hello", 20, 30);
System.out.println(test);
}
}
@Data
是@ToString
,@EqualsAndHashCode
, @Getter
, @Setter
,@RequiredArgsConstructor
的合集。
@Data
的不可变版本。
生成不可变版本的setter
方法。命名为with + 字段名。
即用变化的字段和原先字段生成一个新对象。
如代码:
@AllArgsConstructor
@ToString
class Test {
@With
private String name;
private int age;
public static void main(String[] args) {
Test test = new Test("Hello", 20);
System.out.println(test.withName("World"));
System.out.println(test);
}
}
输出为:
Test(name=World, age=20)
Test(name=Hello, age=20)
withName
接受一个name
参数,并返回一个新的Test
对象。
给实例方法和静态方法加锁,synchronized
关键字在实例或类本身上加锁,而@Synchronized
注解会自动生成一个私有的实例或静态变量,然后在该变量上加锁,因此它的粒度更细。
如代码:
import lombok.Synchronized;
class Test {
@Synchronized
public void testSynchronized() {
System.out.println(1);
}
}
形同于
import lombok.Synchronized;
class Test {
private final Object $lock = new Object[0];
public void testSynchronized() {
synchronized ($lock) {
System.out.println(1);
}
}
}
这个注解在项目中用的最多。它作用于类上,自动为类生成一个log。
@Slf4j
class Test {
public void test() {
log.info("Testing Slf4j");
}
}
形同于
class Test {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Test.class);
public void test() {
log.info("Testing Slf4j");
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。