Lombok深入
Lombok初步介绍
Lombok能干什么
Lombok 是一个 Java 库,它提供了一系列的注解和工具,可以帮助 Java 开发者简化代码,减少样板代码的编写,提高开发效率和代码质量。
使用场景
以下是 Lombok 的全部使用场景:
-
@Getter/@Setter:自动生成 Getter/Setter 方法。
-
@ToString:自动生成 toString 方法。
-
@EqualsAndHashCode:自动生成 equals 和 hashCode 方法。
-
@AllArgsConstructor:自动生成包含所有参数的构造函数。
-
@NoArgsConstructor:自动生成无参构造函数。
-
@RequiredArgsConstructor:自动生成包含必需参数的构造函数。
-
@Data:相当于同时使用了 @Getter/@Setter、@ToString、@EqualsAndHashCode 和 @AllArgsConstructor 注解。
-
@Builder:提供了一种流畅的 API,用于构建不可变的对象。
-
@Singular:在 @Builder 注解中使用,用于指定集合类型的参数。
-
@Log/@Log4j2/@Slf4j:自动生成日志记录器。
-
@NoArgsConstructor(force = true):自动生成无参构造函数,并强制为 final 类型的属性设置默认值。
-
@AllArgsConstructor(staticName = “of”):自动生成包含所有参数的构造函数,并提供一个静态的 of 方法来创建对象。
-
@Value:相当于 @Data 注解,但生成的类是不可变的。
-
@NonNull:用于标记方法参数、字段或局部变量,表示不能为空。
-
@Cleanup:自动关闭资源,如文件、数据库连接等。
-
@Getter(lazy = true):生成懒加载的 Getter 方法。
-
@Delegate:委托给另一个对象处理某些方法。
-
@Wither:生成带有指定属性更新的新对象。
-
@UtilityClass:生成一个 final 类,其中包含了一些静态的工具方法。
-
@FieldNameConstants:生成包含字段名称的常量。
-
@Experimental:标记一个实验性的注解。
总之,Lombok 提供了丰富的注解和工具,可以大大简化 Java 代码的编写,并提高代码的可读性和维护性。根据具体的项目需求和开发习惯,可以选择合适的注解和工具来使用。
注意事项
-
IDE 插件支持:虽然 Lombok 在项目依赖中已经包含了所有必需的类和方法,但需要配合相应的 IDE 插件才能正常工作,否则会出现无法识别注解、生成的方法无法调用等问题。
-
编译时注解处理器:Lombok 注解需要在编译时通过注解处理器生成代码,所以需要确保项目中包含相应的编译时注解处理器。
-
可读性和维护性:虽然 Lombok 可以大大简化代码,但需要在保证可读性和维护性的前提下使用。例如,可以使用 @Getter/@Setter 自动生成 Getter/Setter 方法,但需要注意属性的命名规范,避免出现重复或歧义的属性名称。
-
兼容性:Lombok 可能与某些第三方库或框架存在兼容性问题,需要注意版本号和相关配置,确保不会出现冲突或错误。
-
工具类:使用 @UtilityClass 注解生成的工具类是 final 类型的,无法被继承或扩展。如果需要在工具类中添加实例方法或属性,可以考虑使用 @NoArgsConstructor(access = AccessLevel.PRIVATE) 注解生成私有的无参构造函数。
-
版本更新:Lombok 更新比较频繁,需要及时关注版本更新和变更内容,以便及时升级或调整代码。
要如何使用
Lombok在IDEA中的所需插件
-
安装 Lombok 插件:在 IDEA 中打开插件市场(Marketplace),搜索 Lombok 并安装。
-
配置 Lombok Compiler:在 IDEA 的设置(Settings)中,选择 Build, Execution, Deployment > Compiler > Annotation Processors,勾选 Enable annotation processing,然后在右侧的 Processing 中选择 Configure Annotations,勾选 lombok,保存即可。
-
在项目中使用 Lombok 注解
Lombok在Eclipse中的所需插件
-
安装 Lombok 插件:Lombok 提供了一个名为 lombok.jar 的插件,可以在 Lombok 官网下载,下载后双击运行即可安装。安装完成后,将 lombok.jar 文件复制到 Eclipse 安装目录下的 dropins 目录中。
-
配置 Eclipse:打开 Eclipse 的安装目录,找到 eclipse.ini 文件,在文件最后添加以下内容:
-Xbootclasspath/a:lombok.jar -javaagent:lombok.jar
然后保存文件并重新启动 Eclipse。
-
在项目中使用 Lombok 注解
使用方法
Jar包引入使用
Lombok 的官网 : https://projectlombok.org/
下载最新的 Lombok jar 文件。在官网的首页中,点击 “Download” 按钮,即可进入下载页面。
在下载页面中,你可以选择下载最新版本的 jar 文件或者其他历史版本的 jar 文件。
Maven引入使用
-
在 pom.xml 文件中添加 Lombok 依赖
在 pom.xml 文件的 dependencies 标签中添加以下内容:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency>
-
确保已经在 IDE 中安装 Lombok 插件
-
在项目中使用 Lombok 注解
Lombok 的作用是在编译时自动生成 Java 代码,因此在运行时不需要 Lombok 的 jar 文件,所以将其作用域设置为 provided。
Gradle引入使用
-
在 build.gradle 文件中添加 Lombok 依赖
在 build.gradle 文件中添加以下内容:
dependencies { compileOnly 'org.projectlombok:lombok:1.18.20' annotationProcessor 'org.projectlombok:lombok:1.18.20' }
-
确保已经在 IDE 中安装 Lombok 插件
-
在项目中使用 Lombok 注解
需要注意的是,Lombok 的作用是在编译时自动生成 Java 代码,因此在运行时不需要 Lombok 的 jar 文件。因此,将其作用域设置为
compileOnly
,表示编译时需要 Lombok,但不需要在运行时使用。同时,还需要添加annotationProcessor
依赖,用于处理 Lombok 注解。
Lombok 注解文档
Lombok 注解概览表
以下是常用的 Lombok 注解罗列成的表格,包括注解、注解使用范围、注解作用和注解使用注意事项:
注解 | 使用范围 | 作用 | 注意事项 |
---|---|---|---|
@Data | 类 | 生成所有属性的 Getter/Setter、equals、hashCode、toString 方法 | 注意避免循环引用 |
@Getter/@Setter | 属性 | 生成 Getter/Setter 方法 | 注意避免属性名重复或歧义 |
@NonNull | 参数、属性、方法 | 标记参数、属性、方法返回值不能为空 | 注意参数、属性、方法返回值不能为空 |
@ToString | 类 | 生成 toString 方法 | 注意排除敏感信息 |
@EqualsAndHashCode | 类 | 生成 equals 和 hashCode 方法 | 注意排除敏感信息 |
@NoArgsConstructor | 类 | 生成无参构造函数 | 注意根据需要使用不同的构造函数 |
@RequiredArgsConstructor | 类 | 生成必需参数构造函数 | 注意根据需要使用不同的构造函数 |
@AllArgsConstructor | 类 | 生成所有参数构造函数 | 注意根据需要使用不同的构造函数 |
@Builder | 类、方法 | 生成建造者模式的构建器 | 注意使用时需要使用 @NoArgsConstructor 或 @AllArgsConstructor 生成构造函数 |
@Log | 类、属性、方法 | 自动生成 Logger 对象 | 注意需要在类路径中添加相应的 Log4j 或其他日志库依赖 |
@UtilityClass | 类 | 生成工具类 | 注意生成的工具类是 final 类型,无法被继承或扩展 |
注意事项是使用 Lombok 注解时需要特别注意的地方,使用时需要根据具体情况进行调整和补充。
常用Lombok注解实例详解
@Data
- @Data注解源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
String staticConstructor() default "";
}
@Data作用域
-
@Data注解作用于类上,由 @Target({ElementType.TYPE}) 限定
-
注解仅存在于源码中,在class字节码文件中不包含,由 @Retention(RetentionPolicy.SOURCE) 标记生效
@Data作用
- @Data为类提供get/set方法以及canEqual、equals、hashCode、toString方法:
@Data
public class Car {
}
- 测试实例,现有一类Car,不包含任何属性,通过@Data注解标记后观察其编译输出class文件(见下方),可以看到Lombok为该类生成了canEqual、equals、hashCode、toString方法
public class Car {
public Car() {
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Car)) {
return false;
} else {
Car other = (Car)o;
return other.canEqual(this);
}
}
protected boolean canEqual(Object other) {
return other instanceof Car;
}
public int hashCode() {
int result = true;
return 1;
}
public String toString() {
return "Car()";
}
}
@Data
public class Car {
private String name;
private String color;
}
@Data属性
staticConstructor 为类生成静态构造方法
- String staticConstructor() default “”;
- 查看源码发现包含一个属性staticConstructor,其作用为为类生成静态构造方法
- 测试实例,在类的@Data中staticConstructor属性添加对应String类型命名,即为静态构造方法的命名
//源类
@Data(staticConstructor = "create")
public class Car {
}
//编译后class中包含静态构造方法,方法名以@Data的staticConstructor属性值命名
public static Car create() {
return new Car();
}
- 使用时
Car car = Car.create();
@Data注意事项
- @Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。
- 当使用@Data注解时,则有了@EqualsAndHashCode注解,那么就会在此类中存在equals(Object other) 和 hashCode()方法,且不会使用父类的属性,这就导致了可能的问题:
- 子类无法使用父类中的equals和hashCode方法
- 修复此问题则可以:
- 使用@Getter @Setter @ToString代替@Data并且自定义equals(Object other) 和 hashCode()方法,比如有些类只需要判断主键id是否相等即足矣。
- (推荐)或者在使用@Data时同时加上@EqualsAndHashCode(callSuper=true)注解。
- 修复此问题则可以:
- 子类无法使用父类中的equals和hashCode方法
@EqualsAndHashCode
- EqualsAndHashCode注解源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
String[] exclude() default {};
String[] of() default {};
boolean callSuper() default false;
boolean doNotUseGetters() default false;
EqualsAndHashCode.CacheStrategy cacheStrategy() default EqualsAndHashCode.CacheStrategy.NEVER;
EqualsAndHashCode.AnyAnnotation[] onParam() default {};
boolean onlyExplicitlyIncluded() default false;
/** @deprecated */
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
public @interface AnyAnnotation {
}
public static enum CacheStrategy {
NEVER,
LAZY;
private CacheStrategy() {
}
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {
}
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {
String replaces() default "";
int rank() default 0;
}
}
@EqualsAndHashCode作用域
-
@EqualsAndHashCode注解作用于类上,由 @Target({ElementType.TYPE}) 限定
-
注解仅存在于源码中,在class字节码文件中不包含,由 @Retention(RetentionPolicy.SOURCE) 标记生效
@EqualsAndHashCode作用
- 为类提供canEqual、equals、hashCode方法。这点基本功能在@Data包含,不同的是@EqualsAndHashCode属性较多
- 它默认使用非静态,非瞬态的属性
- 可通过参数exclude排除一些属性
- 可通过参数of指定仅使用哪些属性
- 它默认仅使用该类中定义的属性且不调用父类的方法
- 可通过callSuper=true解决上一点问题。让其生成的方法中调用父类的方法。
@EqualsAndHashCode属性
exclude —— 用于排除一些属性
- String[] exclude() default {};
- 当生成equals与hashCode方法时,排除类中的某些属性
- 例如:以下示例表示在生成equals与hashCode方法时忽略exclude所标记的属性name,即使用除exclude所标记的属性name以外的其他属性
@EqualsAndHashCode(exclude = {"name"})
public class Car {
private String name;
private String color;
}
of —— 指定仅使用哪些属性
- String[] of() default {};
- 当生成equals与hashCode方法时,指定仅使用类中的某些属性
- 例如:以下示例表示生成equals与hashCode方法时仅使用of所标记的属性name,即忽略除of所标记的属性name以外的其他属性
@EqualsAndHashCode(of = {"name"})
public class Car {
private String name;
private String color;
}
callSuper —— 对父类的equals方法的同步调用
- boolean callSuper() default false;
- 当子类进行比较时,同时父类中的属性也需要比较,由此开启使之生效
- 例如:以下示例当callSuper = true时,子类生成的equals中会对父类中的equals同步调用,同时也对父类中的属性进行对比
//父类
@EqualsAndHashCode
public class Transportation {
private String id;
}
//子类
@EqualsAndHashCode(callSuper = true)
public class Car extends Transportation {
private String name;
private String color;
}
- 当callSuper = false(默认)时,子类生成的equals中不包含对父类中的equals同步调用,即无法对父类的属性比较,导致两个子类对象比较出现问题。所以当某一类拥有父类时使用@EqualsAndHashCode注解建议设置属性callSuper = true。
doNotUseGetters —— 在生成equals与hashCode方法时对属性读取方式是否为get方法
- boolean doNotUseGetters() default false;
- 若为true 在生成equals与hashCode方法的具体逻辑时对属性读取方式为 {this.属性名},否则(默认)为属性的get方法
- 注意:前提是该属性存在get方法
- 实例:以下为equals与hashCode局部获取属性方式 对比
// 1- doNotUseGetters = false 且 属性是否存在get方法:否
this.name;
// 2- doNotUseGetters = false 且 属性是否存在get方法:是
this.getName();
// 3- doNotUseGetters = true 且 属性是否存在get方法:否
this.name;
// 4- doNotUseGetters = true 且 属性是否存在get方法:是
this.name;
cacheStrategy 为类添加一个hashCode的缓存变量
- EqualsAndHashCode.CacheStrategy cacheStrategy() default EqualsAndHashCode.CacheStrategy.NEVER;
- cacheStrategy的值为EqualsAndHashCode.CacheStrategy.LAZY时会类添加一个hashCode的缓存变量$hashCodeCache,同时该属性被transient修饰,防止被序列化
- 改属性默认值EqualsAndHashCode.CacheStrategy.NEVER表示从不为hashCode添加缓存,即每次使用都从新计算。
- 修改为EqualsAndHashCode.CacheStrategy.LAZY后使用懒加载模式,只在使用第一次计算hashCode值,后续则从缓存中获取
- 实例:以下是将cacheStrategy设为LAZY懒加载模式为类添加的hashCode的缓存变量
private transient int $hashCodeCache;
- 以下是hashCode使用时具体逻辑,$hashCodeCache的值,也就是hashCode的缓存变量会在第一次计算hashCode后被缓存
- 该变量又被transient 所修饰,不会被序列化
public int hashCode() {
if (this.$hashCodeCache != 0) {
return this.$hashCodeCache;
} else {
int result = 1;
if (result == 0) {
result = -2147483648;
}
this.$hashCodeCache = result;
return result;
}
}
onParam —— 占位符注释 (已弃用)
- EqualsAndHashCode.AnyAnnotation[] onParam() default {};
- 已弃用。占位符注释,用于在生成的代码上放置注释。
onlyExplicitlyIncluded —— 是否仅使用类作为equals与hashCode的生成
- boolean onlyExplicitlyIncluded() default false;
- 若为true,则类中的属性不参与生成的equals与hashCode方法的逻辑
@ToString
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface ToString {
boolean includeFieldNames() default true;
String[] exclude() default {};
String[] of() default {};
boolean callSuper() default false;
boolean doNotUseGetters() default false;
boolean onlyExplicitlyIncluded() default false;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {
}
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {
int rank() default 0;
String name() default "";
}
}
@ToString作用域
-
@ToString注解作用于类上,由 @Target({ElementType.TYPE}) 限定
-
注解仅存在于源码中,在class字节码文件中不包含,由 @Retention(RetentionPolicy.SOURCE) 标记生效
@ToString作用
- 为类提供toString方法
@ToString
public class Car {
public String name;
private String color;
}
- 例如:以上示例生成的class文件中包含有
public String toString() {
return "Car(name=" + this.name + ", color=" + this.color + ")";
}
@ToString属性
includeFieldNames —— 生成的toString方法是否包含属性名
- boolean includeFieldNames() default true;
- includeFieldNames默认为false,includeFieldNames为true时生成的toString方法不包含属性名
- 例如:对比@ToString作用示例,includeFieldNames = true为以下
public String toString() {
return "Car(" + this.name + ", " + this.color + ")";
}
exclude —— 用于排除一些属性
- String[] exclude() default {};
- 当生成toString方法时,排除类中的某些属性
- 例如:以下示例表示在生成equals与toString方法时忽略exclude所标记的属性name,即使用除exclude所标记的属性name以外的其他属性
@ToString(exclude = {"name"})
public class Car {
public String name;
private String color;
}
//生成
public String toString() {
return "Car(color=" + this.color + ")";
}
of —— 指定仅使用哪些属性
- String[] of() default {};
- 当生成toString方法时,指定仅使用类中的某些属性
- 例如:以下示例表示生成toString方法时仅使用of所标记的属性name,即忽略除of所标记的属性name以外的其他属性
@EqualsAndHashCode(of = {"name"})
public class Car {
private String name;
private String color;
}
//生成
public String toString() {
return "Car(name=" + this.name + ")";
}
callSuper —— 生成toString方法时是否同时调用父类的toString方法
- boolean callSuper() default false;
- 当callSuper为默认为false时,生成的toString方法只包含当前类中的属性
- 当callSuper为设置为true时,生成的toString方法中包含父类的toString方法
- 例如:以下是callSuper为设置为true时的效果
public String toString() {
String var10000 = super.toString();
return "Car(super=" + var10000 + ", name=" + this.name + ", color=" + this.color + ")";
}
doNotUseGetters —— 在生成toString方法时对属性读取方式是否为get方法
- boolean doNotUseGetters() default false;
- 若为true 在生成toString方法时对属性读取方式为 {this.属性名},否则(默认)为属性的get方法
- 注意:前提是该属性存在get方法
- 实例:以下为toString获取属性方式 对比
// 1- doNotUseGetters = false 且 属性是否存在get方法:否
return "Car(name=" + this.name + ", color=" + this.color + ")";
// 2- doNotUseGetters = false 且 属性是否存在get方法:是
return "Car(name=" + this.getName()+ ", color=" + this.getColor() + ")";
// 3- doNotUseGetters = true 且 属性是否存在get方法:否
return "Car(name=" + this.name + ", color=" + this.color + ")";
// 4- doNotUseGetters = true 且 属性是否存在get方法:是
return "Car(name=" + this.name + ", color=" + this.color + ")";
onlyExplicitlyIncluded —— 是否仅使用类作为toString方法的生成
- boolean onlyExplicitlyIncluded() default false;
- 若为true,则当前类中的属性不参与生成的toString方法,相当于当前类中没有属性
@Getter / @Setter
- Get、Set这俩双胞胎的源码还是有点区别的
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Getter {
AccessLevel value() default AccessLevel.PUBLIC;
Getter.AnyAnnotation[] onMethod() default {};
boolean lazy() default false;
/** @deprecated */
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
public @interface AnyAnnotation {
}
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Setter {
AccessLevel value() default AccessLevel.PUBLIC;
Setter.AnyAnnotation[] onMethod() default {};
Setter.AnyAnnotation[] onParam() default {};
/** @deprecated */
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
public @interface AnyAnnotation {
}
}
@作用域
-
@Getter/@Setter注解作用于类和字段上,由 @Target({ElementType.FIELD, ElementType.TYPE}) 限定
-
注解仅存在于源码中,在class字节码文件中不包含,由 @Retention(RetentionPolicy.SOURCE) 标记生效
@作用
- 在类上:为类中的所有非静态成员变量生成Getter和Setter方法
@Setter
public class Car {
public String name;
@Getter
private String color;
}
- 例如:以上示例为类生成了name属性的set方法,为color属性生成了get/set方法,生成效果如下
public class Car {
public String name;
private String color;
public Car() {
}
public void setName(String name) {
this.name = name;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return this.color;
}
}
@Getter/@Setter属性
value —— 生成get/set方法时指定访问级别
- AccessLevel value() default AccessLevel.PUBLIC;
- value用于标记改变生成get/set方法时指定访问级别,其中AccessLevel为:
- PUBLIC —— 公开的
- MODULE —— 同模块可访问
- PROTECTED —— 受保护的
- PACKAGE —— 同一包下可访问
- PRIVATE —— 私有的
- NONE —— 无权访问(使@Getter/@Setter不生效)
onMethod —— 生成get/set方法时在方法上添加对应注解
- Getter.AnyAnnotation[] onMethod() default {}; / Setter.AnyAnnotation[] onMethod() default {};
- 为生成后的get/set方法添加对应注解,一般书写形式为:(onMethod = @__(@MyTest1))
@Getter(onMethod = @__(@MyTest1))
public class Car {
@Setter(onMethod = @__(@MyTest2))
protected String name;
private String color;
}
- 实例:以上示例片段表示,为生成的get/set方法添加对应注解:生成的get方法上自动添加@MyTest1注解,生成的set方法上自动添加@MyTest2注解,生成结果如下。(注意:这里的两个测试注解MyTest1、MyTest2的作用域必须是方法且为运行时注解,即必须有 @Target({ElementType.METHOD}) 限定注解作用域, @Retention(RetentionPolicy.RUNTIME) 限定注解保留在运行时)若使用其他注解同理。
public class Car {
protected String name;
private String color;
public Car() {
}
@MyTest1
public String getName() {
return this.name;
}
@MyTest1
public String getColor() {
return this.color;
}
@MyTest2
public void setName(String name) {
this.name = name;
}
}
@Getter的lazy —— get懒加载
- boolean lazy() default false;
- 提高代码效率,自动管理线程安全的问题,不会存在重复赋值的问题.
//不使用懒加载
public class Car {
@Getter
private final String msg = "Hello Lombok!";
}
//不使用懒加载的编译结果
public class Car {
private final String msg = "Hello Lombok!";
public Car() {
}
public String getMsg() {
Objects.requireNonNull(this);
return "Hello Lombok!";
}
}
- 实例:以上片段为在类中给字段赋值,在不使用懒加载的情况下,在多线程中就会出现多次赋值的情况(注意这里必须是被final修饰的变量),以下是使用懒加载的编译情况
//使用懒加载
public class Car {
@Getter(lazy = true)
private final String msg = "Hello Lombok!";
}
//使用懒加载的编译结果
public class Car {
private final AtomicReference<Object> msg = new AtomicReference();
public Car() {
}
public String getMsg() {
Object value = this.msg.get();
if (value == null) {
synchronized(this.msg) {
value = this.msg.get();
if (value == null) {
String actualValue = "Hello Lombok!";
value = "Hello Lombok!" == null ? this.msg : "Hello Lombok!";
this.msg.set(value);
}
}
}
return (String)(value == this.msg ? null : value);
}
}
@Setter的onParam —— 占位符注释 (已弃用)
- Setter.AnyAnnotation[] onParam() default {};
- 已弃用。占位符注释,用于在生成的代码上放置注释。
@NoArgsConstructor
- @NoArgsConstructor注解内
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface NoArgsConstructor {
String staticName() default "";
NoArgsConstructor.AnyAnnotation[] onConstructor() default {};
AccessLevel access() default AccessLevel.PUBLIC;
boolean force() default false;
/** @deprecated */
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
public @interface AnyAnnotation {
}
}
@NoArgsConstructor作用域
-
@NoArgsConstructor注解作用于类上,由 @Target({ElementType.TYPE}) 限定
-
注解仅存在于源码中,在class字节码文件中不包含,由 @Retention(RetentionPolicy.SOURCE) 标记生效
@NoArgsConstructor 作用
- @NoArgsConstructor 注解用于生成无参构造方法。在 Java 类中,如果没有手动定义构造方法,Java 编译器会默认生成一个无参构造方法,但如果手动添加了构造方法,则默认无参构造方法会被覆盖,需要手动添加无参构造方法。使用 @NoArgsConstructor`注解可以自动生成无参构造方法,省去了手动添加的步骤,简化了代码。
- @NoArgsConstructor 注解的作用域
@NoArgsConstructor`注解的作用域是类。
- @NoArgsConstructor 注解的属性
@NoArgsConstructor 注解没有属性。
下面是一个示例代码,使用 @NoArgsConstructor`注解生成无参构造方法:
import lombok.NoArgsConstructor;
@NoArgsConstructor
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
使用 @NoArgsConstructor 注解后,可以省略无参构造方法的手动编写,代码简化为:
import lombok.NoArgsConstructor;
@NoArgsConstructor
public class Person {
private String name;
private int age;
}
这里的 Person类使用 @NoArgsConstructor
注解生成了无参构造方法,无需手动添加。