Lombok注解速查
Lombok
一个帮你写代码的神器,具体介绍请移步Lombok官网
使用步骤:
- Idea 安装 Lombok 插件
- Maven 引入
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
Lombok的scope=provided
,说明它只在编译
阶段生效,不需要打入包中。事实正是如此,Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件。
3.使用 lomback 注解
1. @Getter and @Setter
使用@Getter
或@Setter
注释任何字段,以使lombok自动生成默认的getter
/ setter
。
默认的getter
只是返回该字段,如果该字段被称为foo,则名为getFoo(如果该字段的类型为boolean,则为isFoo)。
默认生成的 getter
/ setter
方法是公共
的,你可以指定一个AccessLevel
来设置访问级别。访问级别有PUBLIC
,PROTECTED
,PACKAGE
,PRIVATE
四种。
你还可以在类上添加@Getter
或@Setter
注解。在这种情况下,就好像你使用该注解来注释该类中的所有非静态字段
一样。
你始终可以使用特殊的AccessLevel.NONE
访问级别来手动禁用任何字段的getter
/ setter
生成。这时你可以覆盖类上的@Getter
,@Setter
或 @Data
注释的行为。
使用 Lombok Java 代码:
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class GetterSetterExample {
@Getter(AccessLevel.NONE)
private String code;
@Getter(AccessLevel.PROTECTED)
private boolean success;
}
编译后:
public class GetterSetterExample {
private String code;
private boolean success;
public void setCode(final String code) {
this.code = code;
}
public void setSuccess(final boolean success) {
this.success = success;
}
protected boolean isSuccess() {
return this.success;
}
}
2. @ToString
生成toString()
方法的实现。
默认情况下,它将使用所有非静态
字段
属性 | 描述 |
---|---|
includeFieldNames | 打印时是否显示字段名称,默认为 true |
of | 打印字段;如果存在,只会打印标识的字段 |
exclude | 跳过字段;和of 相反;不会打印标识的字段。 也可以在字段上使用 @ToString.Exclude 跳过。 |
callSuper | toString是否包含超类实现的结果,默认为 false |
doNotUseGetters | 默认为 false;如果值为true,则Lombok会直接获取 field 而不是通过get方法获取值 |
使用 Lombok Java 代码:
import lombok.ToString;
@ToString(callSuper = true)
public class ToStringExample extends GetterSetterExample {
private static final int STATIC_VAR = 10;
private String name;
@ToString.Exclude
private int id;
}
编译后:
public class ToStringExample extends GetterSetterExample {
private static final int STATIC_VAR = 10;
private String name;
private int id;
public ToStringExample() {
}
public String toString() {
return "ToStringExample(super=" + super.toString() + ", name=" + this.name + ")";
}
}
3. @EqualsAndHashCode
生成equals(Object other)
和hashCode()
方法的实现。
默认情况下,它将使用所有非静态,非瞬态
字段。
属性 | 描述 |
---|---|
of | 打印字段;如果存在,只会包含标识的字段 |
exclude | 跳过字段;和of 相反;不会包含标识的字段。 也可以在字段上使用 @EqualsAndHashCode.Exclude 跳过。 |
callSuper | equals/hashCode是否包含超类实现的结果,默认为 false |
doNotUseGetters | 默认为 false;如果值为true,则Lombok会直接获取 field 而不是通过get方法获取值(如果可用) |
使用 Lombok Java 代码:
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true, exclude = {"name"})
public class EqualsAndHashCodeExample extends GetterSetterExample {
private static final int STATIC_VAR = 10;
private int id;
private String name;
}
编译后:
public class EqualsAndHashCodeExample extends GetterSetterExample {
private static final int STATIC_VAR = 10;
private int id;
private String name;
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof EqualsAndHashCodeExample)) {
return false;
} else {
EqualsAndHashCodeExample other = (EqualsAndHashCodeExample)o;
if (!other.canEqual(this)) {
return false;
} else if (!super.equals(o)) {
return false;
} else {
return this.id == other.id;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof EqualsAndHashCodeExample;
}
public int hashCode() {
int PRIME = true;
int result = super.hashCode();
result = result * 59 + this.id;
return result;
}
}
4. @AllArgsConstructor、@RequiredArgsConstructor、@NoArgsConstructor
生成构造函数
属性 | 描述 |
---|---|
access | 设置构造器的权限。 |
staticName | 如果生成静态的构造方法,那么原来的实例构造方法将会被私有(private),然后创建一个你指定名称的静态构造方法,并且是public的 |
注解 | 描述 |
---|---|
@AllArgsConstructor | 生成一个包含所有变量的构造函数。 参数顺序与属性顺序一致。 标有@NonNull 的字段会进行非空校验。 |
@NoArgsConstructor | 生成没有参数的构造函数。 当类中有final字段没有被初始化时,编译器会报错,但是也可用 @NoArgsConstructor(force = true) 将所有final字段都将初始化为0/false/null 。 对于具有约束的字段(例如@NonNull 字段),不会生成任何检查。 |
@RequiredArgsConstructor | 会生成一个无参构造方法或者一个包含以final修饰的未经初始化的字段以及标识了@NotNull 的变量的有参构造方法。 |
使用 Lombok Java 代码:
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor(staticName = "myCustom")
public class ConstructorExample {
private static final int STATIC_VAR = 10;
private int id;
private String name;
}
编译后:
public class ConstructorExample {
private static final int STATIC_VAR = 10;
private int id;
private String name;
public ConstructorExample(final int id, final String name) {
this.id = id;
this.name = name;
}
private ConstructorExample() {
}
public static ConstructorExample myCustom() {
return new ConstructorExample();
}
}
使用 Lombok Java 代码:
import lombok.RequiredArgsConstructor;
import lombok.NonNull;
@RequiredArgsConstructor
public class RequiredArgsConstructorExample {
private final int id;
@NonNull
private String name;
}
编译后:
public class RequiredArgsConstructorExample {
private final int id;
@NonNull
private String name;
public ConstructorExample(final int id, @NonNull final String name) {
if (name == null) {
throw new NullPointerException("name is marked non-null but is null");
} else {
this.id = id;
this.name = name;
}
}
}
5. @Data
@Data
是@ToString
、@EqualsAndHashCode
、@Getter
、@Setter
、@RequiredArgsConstructor
五个注解的集合。
使用 Lombok Java 代码:
import lombok.Data;
@Data
public class DataExample {
private static final int STATIC_VAR = 10;
private int id;
private String name;
}
编译后:
public class DataExample {
private static final int STATIC_VAR = 10;
private int id;
private String name;
public DataExample() {
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public void setId(final int id) {
this.id = id;
}
public void setName(final String name) {
this.name = name;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof DataExample)) {
return false;
} else {
DataExample other = (DataExample)o;
if (!other.canEqual(this)) {
return false;
} else if (this.getId() != other.getId()) {
return false;
} else {
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof DataExample;
}
public int hashCode() {
int PRIME = true;
int result = 1;
int result = result * 59 + this.getId();
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
return result;
}
public String toString() {
return "DataExample(id=" + this.getId() + ", name=" + this.getName() + ")";
}
}
6. @Value
@Value
注解和@Data
类似,区别在于它会把所有成员变量默认定义为private final
修饰,并且不会
生成set方法。
7. @Builder
构建者模式 只能标注到类上,将生成类的一个当前流程的一种链式构造工厂,如下:
BuilderExample builderExample = BuilderExample.builder().name("路飞").listAdd("你好").build();
System.out.println(builderExample.toString());
运行输出:
BuilderExample(id=1, name=路飞, list=[你好])
常配合@Singular
注解使用,@Singular
注解使用在jdk内部集合类型的属性,Map类型的属性以及Guava的com.google.common.collect 的属性上。
例如 未标注@Singular的属性,一般setter时,会直接覆盖原来的引用,标注了@Singular
的属性,集合属性支持添加
操作,会在属性原来的基础上增加。
使用@Builder.Default
来设置默认值
使用 Lombok Java 代码:
import lombok.Builder;
import lombok.ToString;
import lombok.Singular;
import java.util.Set;
@Builder
@ToString
public class BuilderExample {
@Builder.Default
private final int id = 1;
private final String name;
@Singular("listAdd")
private final List<String> list;
}
编译后:
public class BuilderExample {
private final int id;
private final String name;
private final List<String> list;
private static int $default$id() {
return 1;
}
BuilderExample(final int id, final String name, final List<String> list) {
this.id = id;
this.name = name;
this.list = list;
}
public static BuilderExample.BuilderExampleBuilder builder() {
return new BuilderExample.BuilderExampleBuilder();
}
public String toString() {
return "BuilderExample(id=" + this.id + ", name=" + this.name + ", list=" + this.list + ")";
}
public static class BuilderExampleBuilder {
private boolean id$set;
private int id$value;
private String name;
private ArrayList<String> list;
BuilderExampleBuilder() {
}
public BuilderExample.BuilderExampleBuilder id(final int id) {
this.id$value = id;
this.id$set = true;
return this;
}
public BuilderExample.BuilderExampleBuilder name(final String name) {
this.name = name;
return this;
}
public BuilderExample.BuilderExampleBuilder listAdd(final String listAdd) {
if (this.list == null) {
this.list = new ArrayList();
}
this.list.add(listAdd);
return this;
}
public BuilderExample.BuilderExampleBuilder list(final Collection<? extends String> list) {
if (list == null) {
throw new NullPointerException("list cannot be null");
} else {
if (this.list == null) {
this.list = new ArrayList();
}
this.list.addAll(list);
return this;
}
}
public BuilderExample.BuilderExampleBuilder clearList() {
if (this.list != null) {
this.list.clear();
}
return this;
}
public BuilderExample build() {
List list;
switch(this.list == null ? 0 : this.list.size()) {
case 0:
list = Collections.emptyList();
break;
case 1:
list = Collections.singletonList(this.list.get(0));
break;
default:
list = Collections.unmodifiableList(new ArrayList(this.list));
}
int id$value = this.id$value;
if (!this.id$set) {
id$value = BuilderExample.$default$id();
}
return new BuilderExample(id$value, this.name, list);
}
public String toString() {
return "BuilderExample.BuilderExampleBuilder(id$value=" + this.id$value + ", name=" + this.name + ", list=" + this.list + ")";
}
}
}
8. @Accessors
链式风格 @Accessors
注解用于配置lombok如何生成
getter和setter。
属性 | 描述 |
---|---|
fluent | 默认false;设置为true时getter和setter方法将省略get和set前缀,且setter方法返回当前对象。 |
chain | 默认false;设置为true时setter方法返回当前对象 |
prefix | 用于设置生成getter和setter方法的字段名会忽视指定前缀(属性必须为驼峰式命名) |
new AccessorsExample().id(1).name("路飞");
使用 Lombok Java 代码:
@Getter
@Setter
@Accessors(fluent = true, prefix = "a")
public class AccessorsExample {
private int aId;
private String aName;
}
编译之后为:
public class AccessorsExample {
private int aId;
private String aName;
public AccessorsExample() {
}
public int id() {
return this.aId;
}
public String name() {
return this.aName;
}
public AccessorsExample id(final int aId) {
this.aId = aId;
return this;
}
public AccessorsExample name(final String aName) {
this.aName = aName;
return this;
}
}
9. @Slf4j、@Log4j2
在需要打印日志的类中使用,项目中使用slf4j、log4j2日志框架
相当于:
private final Logger log = LoggerFactory.getLogger(当前类名.class);
10. @NonNull
该注解快速判断是否为空,为空抛出java.lang.NullPointerException。
11. @Synchronized
注解自动添加到同步机制,生成的代码并不是直接锁方法,而是锁代码块, 作用范围是方法上。
12. @Cleanup
注解用于确保已分配的资源被释放(IO的连接关闭)。