Lombok组件使用介绍
程序员文章站
2022-05-03 23:42:19
Lombokmaven org.projectlombok lombok 1.16.18 --在编译阶段生效 provided ...
Lombok
- maven
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
--在编译阶段生效
<scope>provided</scope>
</dependency>
-
原理
通常解析类信息,使用反射,反射的方法局限性较大。首先,它必须定义@Retention为RetentionPolicy.RUNTIME,只能在运行时通过反射来获取注解值,使得运行时代码效率降低。
而 JSR 269 之后我们可以在 Javac的编译期利用注解做这些事情,自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。
1)javac对源代码进行分析,生成语法
2)运行过程中调用实现了"JSR 269 API"的处理类
例如lombok中getter的处理类HandleGetter
lombok的处理类基本遵循Handlexxx命名规范
3)以完成它自己的逻辑,包括修改第一步骤得到的语法.
4)javac使用修改后的语法,生成字节码文件 -
部分注解/属性
@Getter
用于自动生成get方法。Boolean类型为is开头。
//标注在类,字段
@Target({ElementType.FIELD, ElementType.TYPE})
//只在源文件中保留,编译时执行
@Retention(RetentionPolicy.SOURCE)
public @interface Getter {
//所生成get方法的访问权限
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
//在生成的方法上增加注解
//因为语法受到编译器版本的影响已经弃用
AnyAnnotation[] onMethod() default {};
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
//是否懒加载
//现在需要对一个成员变量初始化,但是初始化过程复杂
boolean lazy() default false;
}
java文件
@Getter(value = AccessLevel.PUBLIC)
public class User {
private String userName;
@Getter(value = AccessLevel.NONE)
private String age;
private boolean isAdmin;
@Getter(lazy = true)
private final String[] roleCode = selectRoleCode();
private String[] selectRoleCode() {
String[] result = new String[10000];
for (int i = 0; i < result.length; i++) {
result[i] = String.valueOf(Math.asin(i));
}
return result;
}
}
class文件
public class User {
private String userName;
private String age;
private boolean isAdmin;
//考虑线程安全使用AtomicReference原子读写的对象
private final AtomicReference<Object> roleCode = new AtomicReference();
public User() {
}
private String[] selectRoleCode() {
String[] result = new String[10000];
for(int i = 0; i < result.length; ++i) {
result[i] = String.valueOf(Math.asin((double)i));
}
return result;
}
public String getUserName() {
return this.userName;
}
public boolean isAdmin() {
return this.isAdmin;
}
public String[] getRoleCode() {
Object value = this.roleCode.get();
//线程同步锁双重检查
//第一次n线程同时访问,外层检查value为空,多线程排队获取锁
//第二次n线程同时方法,外层检查value不为空,多线程不再等待获取同步代码块锁,避免了不必要的排队现象
if (value == null) {
synchronized(this.roleCode) {
value = this.roleCode.get();
if (value == null) {
String[] actualValue = this.selectRoleCode();
value = actualValue == null ? this.roleCode : actualValue;
this.roleCode.set(value);
}
}
}
return (String[])((String[])(value == this.roleCode ? null : value));
}
}
@Setter
自动生成set方法
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Setter {
//所生成set方法的访问权限
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
//为生成的set方法增加注解,弃用
AnyAnnotation[] onMethod() default {};
//为生成方法内的参数增加注解,弃用
AnyAnnotation[] onParam() default {};
@Deprecated
@Retention(RetentionPolicy.SOURCE)
@Target({})
@interface AnyAnnotation {}
}
java文件
@Setter(value = AccessLevel.PUBLIC)
public class User {
private String userName;
@Setter(value = AccessLevel.NONE)
private String age;
private boolean isAdmin;
}
class文件
public class User {
private String userName;
private String age;
private boolean isAdmin;
public User() {
}
public void setUserName(final String userName) {
this.userName = userName;
}
public void setAdmin(final boolean isAdmin) {
this.isAdmin = isAdmin;
}
}
@Data
自动生成成员变量的get/set/toString/hasCode/equals方法
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
//生成一个静态方法,返回一个调用相应的构造方法产生的对象
String staticConstructor() default "";
}
java文件
@Data(staticConstructor = "test")
public class User {
private String userName;
private String age;
private boolean isAdmin;
}
class文件
public class User {
private String userName;
private String age;
private boolean isAdmin;
private User() {
}
public static User test() {
return new User();
}
public String getUserName() {
return this.userName;
}
public String getAge() {
return this.age;
}
public boolean isAdmin() {
return this.isAdmin;
}
public void setUserName(final String userName) {
this.userName = userName;
}
public void setAge(final String age) {
this.age = age;
}
public void setAdmin(final boolean isAdmin) {
this.isAdmin = isAdmin;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User)) {
return false;
} else {
User other = (User)o;
if (!other.canEqual(this)) {
return false;
} else {
label39: {
Object this$userName = this.getUserName();
Object other$userName = other.getUserName();
if (this$userName == null) {
if (other$userName == null) {
break label39;
}
} else if (this$userName.equals(other$userName)) {
break label39;
}
return false;
}
Object this$age = this.getAge();
Object other$age = other.getAge();
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
return false;
}
if (this.isAdmin() != other.isAdmin()) {
return false;
} else {
return true;
}
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof User;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $userName = this.getUserName();
int result = result * 59 + ($userName == null ? 43 : $userName.hashCode());
Object $age = this.getAge();
result = result * 59 + ($age == null ? 43 : $age.hashCode());
result = result * 59 + (this.isAdmin() ? 79 : 97);
return result;
}
public String toString() {
return "User(userName=" + this.getUserName() + ", age=" + this.getAge() + ", isAdmin=" + this.isAdmin() + ")";
}
}
@ToString
自动生成toString()方法
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ToString {
//打印是否包含字段名称
boolean includeFieldNames() default true;
//是否只通过标记字段来标记使用的字段
boolean onlyExplicitlyIncluded() default false;
//是否toString方法体内会带上超类的toString方法
boolean callSuper() default false;
//剔除字段,或者注解变量标记为剔除字段
String[] exclude() default {};
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {}
//包含字段,或者注解变量标记为包含字段
String[] of() default {};
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {}
}
java文件
@ToString
public class Example {
private String name;
private Shape shape = new Square(5, 10);
private String[] tags = new String[]{"1", "2", "3"};
/**
* 标记 @ToString.Exclude
* toString方法不包含此字段
*/
@ToString.Exclude
private int id;
@ToString(callSuper = true, includeFieldNames = false)
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
}
public static class Shape {
@Override
public String toString() {
return "Shape[" + this.hashCode() + "]";
}
}
}
class文件
public class Example {
private String name;
private Example.Shape shape = new Example.Square(5, 10);
private String[] tags = new String[]{"1", "2", "3"};
private int id;
public Example() {
}
public String toString() {
return "Example(name=" + this.name + ", shape=" + this.shape + ", tags=" + Arrays.deepToString(this.tags) + ")";
}
public static class Shape {
public Shape() {
}
public String toString() {
return "Shape[" + this.hashCode() + "]";
}
}
public static class Square extends Example.Shape {
private final int width;
private final int height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
public String toString() {
return "Example.Square(super=" + super.toString() + ", " + this.width + ", " + this.height + ")";
}
}
}
结果
Example(name=null, shape=Example.Square(super=Shape[471910020], 5, 10), tags=[1, 2, 3])
@EqualsAndHashCode
自动生成Equals方法和hashcode方法
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
//剔除字段,或者注解变量标记为剔除字段
String[] exclude() default {};
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {}
//包含字段,或者注解变量标记为包含字段
String[] of() default {};
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {}
}
@SneakyThrows
自动生成try-catch代码块抛出异常
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.SOURCE)
public @interface SneakyThrows {
//跑出的错误类型
Class<? extends Throwable>[] value() default java.lang.Throwable.class;
}
java文件
public class Test {
@SneakyThrows
public void doSomething(){
System.out.println("hello world...");
}
}
class文件
public class Test {
public Test() {
}
public void doSomething() {
try {
System.out.println("hello world...");
} catch (Throwable var2) {
throw var2;
}
}
}
本文地址:https://blog.csdn.net/qq_33026561/article/details/109609005