Lombok 是一种 Java实用工具,可用来帮助开发人员消除Java的冗长,尤其是对于简单的Java对象(POJO), 它通过注释实现这一目的。一个标准的Java bean 一般具有若干属性,每个属性具有getter()和setter()方法,Lombok中也用到了注解,但是它并没有用到反射,而是通过在代码编译时期动态将注解替换为具体的代码。所以JVM实际运行的代码,和我们手动编写的包含了各种工具方法的类相同。
@Data:相当于同时加上以下注解@Setter @Getter,@ToString,@EqualsAndHashCode,作用于类中。
例如:@Data
public class Person {}
@builder:在JavaBean中使用,使用此注解可通过builder方式初始化对象。
例如:
@Builder(toBuilder = true)
public class UserInfo {}
赋值:UserInfo userInfo = UserInfo.builder()
.name("zzl")
.email("bgood@sina.com")
.build();
修改(要添加toBuilder = true):UserInfo userInfo = UserInfo.builder()
.name("zzl")
.email("bgood@sina.com")
.build();
@getter、@setter:在JavaBean中使用,使用此注解会生成对应的getter,setter方法。只对该类中的成员变量生效,static不产生效果,final仅生成 Getter 方法(final 类型字段不可更改)。
例如:@Getter@Setter
private String name;
@Getter(AccessLevel.NONE) //单独指定该字段不生成 Getter 方法
private String name;
@NonNull:使用在类中的方法/构造器
中(参数判非空),或者使用在字段上(该字段值不为空),该注解快速判断是否为空,如果为空,则抛出java.lang.NullPointerException。
例如:@Setter@Getter@NonNull
private List<Person> member;
public void test(@NonNull String s) {}
@Synchronized:该注解自动添加到同步机制,有趣的是,生成的代码并不是直接锁方法,而是锁代码块。
例如:@Synchronized
public String synchronizedFormat(Date date) {}
@NoArgsConstructor:生成对应的无参构造方法;
@AllArgsConstructor:生成对应的有参构造方法;
例如:
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserInfo {}
@RequiredArgsConstructor:注解在类上,会生成构造方法(可能带参数也可能不带参数)。如果带参数,这参数只能是以 final 修饰的未经初始化的字段或者是以 @NonNull 注解的未经初始化的字段。
// 使用注解
@RequiredArgsConstructor(staticName = "hangge")
public class Shape {
private int x;
@NonNull
private double y;
@NonNull
private String name;
}
// 不使用注解
public class Shape {
private int x;
private double y;
private String name;
public Shape(double y, String name){
this.y = y;
this.name = name;
}
public static Shape hangge(double y, String name){
return new Shape(y, name);
}
}
@ToString:只能放在类上,生成toStirng方法,还有多个属性可以进一步设置。
callSuper //是否输出父类的toString方法,默认为false
includeFieldNames //是否包含字段名称,默认为true
exclude //排除生成tostring的字段
例如:@ToString(callSuper = true,exclude ={"name"})
public class Person { }
@EqualsAndHashCode:生成equals方法和hashCode方法;
@Slf4j:在需要打印日志的类中使用,当项目中使用了slf4j打印日志框架时使用该注解,会简化日志的打印流程,只需调用info方法即可;
@Slf4j(topic="customLogger.test") //指定logger,customLogger是Logger的name,test是调用log的类名
@Log:在类上开启 Log 注解,即可进行日志相关操作
@Log4j:在需要打印日志的类中使用,当项目中使用了log4j打印日志框架时使用该注解,会简化日志的打印流程,只需调用info方法即可;
自动生成以下代码
private static final Logger log = Logger.getLogger(User.class.getName());
@Cleanup:注释可用于确保已分配的资源被释放,如IO的连接关闭。
例如: @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
val:类似javascript中的var。直接使用。
val example = new ArrayList<String>();
@SneakyThrows:可以对受检异常进行捕捉并抛出。
/*
* 若不使用@SneakyThrows注解,newInsstance方法会要求抛出InstantiationException,
* IllegalAccessException异常,且调用sneakyThrowsTest()的地方需要捕获这些异常,
* 加上@SneakyThrows注解之后就不需要捕获异常信息。
*/
@SneakyThrows
private void sneakyThrowsTest(){
SneakyThrowsDemo.class.newInstance();
}
@Accessors(chain = true):链式风格,在调用set方法时,返回这个类的实例对象
@Accessors(chain = true)
@Setter
@Getter
public class Student {
private String name;
private int age;
}
Student student = new Student()
.setAge(24)
.setName("zs");
@Accessors(fluent = true):与chain=true类似,区别在于getter和setter不带set和get前缀。
User user=new User().setAge(31).setName("pollyduan");
@RequiredArgsContructor(staticName = “of”):生成一个静态方法,用于构建本类对象,与@NonNull联用,指定那些属性是本方法参数
@Accessors(chain = true)
@Setter
@Getter
@RequiredArgsConstructor(staticName = "of")
public class Student {
@NonNull
private String name;
private int age;
}
Student student = Student.of("zs");
@Delegate:代理模式
public class User {
private interface SimpleCollection {
boolean add(String item);
boolean remove(Object item);
}
@Delegate(types = SimpleCollection.class)
private final Collection<String> collection = new ArrayList<String>();
public static void main(String[] args) {
User user=new User();
user.add("item1");//实际上加到collection中去了
}
}
@UtilityClass:将当前类变成工具类。当前类的所有方法添加static。
@UtilityClass
public class UserInfo {}
@ExtensionMethod:拓展方法,向现有类型“添加”方法,而无需创建新的派生类型。
@ExtensionMethod({Arrays.class, Extensions.class})
public class Example {
public static void main(String[] args) {
int[] intArray = {5, 3, 8, 2};
intArray.sort();
int num = 1;
num = num.increase();
Arrays.stream(intArray).forEach(System.out::println);
System.out.println("num = " + num);
}
}
class Extensions {
public static int increase(int num) {
return ++num;
}
}
生成后:
public class Example {
public Example() {
}
public static void main(String[] args) {
int[] intArray = new int[]{5, 3, 8, 2};
Arrays.sort(intArray);
int num = 1;
int num = Extensions.increase(num);
IntStream var10000 = Arrays.stream(intArray);
PrintStream var10001 = System.out;
System.out.getClass();
var10000.forEach(var10001::println);
System.out.println("num = " + num);
}
}
@FieldDefaults
@Wither:生成withXXX方法,返回类实例
@RequiredArgsConstructor
public class Example {
private @Wither final int foo;
}
生成后:
public class Example {
private final int foo;
public Example(int foo) {
this.foo = foo;
}
public Example withFoo(int foo) {
return this.foo == foo ? this : new Example(foo);
}
}
@Helper