1 什么是 Lombok
官网介绍:
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
翻译过来就是:
Project Lombok是一个java库,可以自动插入到编辑器和构建工具中,使java更加丰富多彩。
不要再编写另一个getter或equals方法,只要有一个注释,类就有功能齐全的构建器,自动记录日志变量,等等。
就是我使用注释就可以代替那些 set和get方法 、构造方法等,消除程序的冗长,简化代码
没使用Lombok之前:
public class User implements Serializable {
private int age; //年龄
private String username; //用户姓名
private String email;//用户邮箱
public User(String username, int age) {
this.username=username;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
使用lombok之后:
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private int age;
private String username;
private String email;
}

2 如何准备Lombok
首先在pom.xml文件中引入lombok的依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
然后 配置idea( setting ->plugin->lombok->install->重启idea)
3 lombok的方法
1 @Data
相当于使用
@Setter
、
@Getter
、
@RequiredArgsConstructor
、
@ToString
、
@EqualsAndHashCode 为这个实体类自动添加set方法 get方法 有参构造函数 toString方法 重写Hashcode函数
2 @Setter
给实体类自动创建Setter方法,如果标记在类上就是给这个类的所有属性创建Setter方法,如果标记在属性上就是给这个属性创建Setter方法
import java.io.Serializable;
public class User implements Serializable {
@Setter
private int age;
private String username;
private String email;
}
效果:
public class testController {
@RequestMapping("/hello")
public User newuser()
{
User user=new User();
user.setAge(1);
user.setUsername("222");
return user;
}
}
标记在类上:
@Setter
public class User implements Serializable {
private int age;
private String username;
private String email;
}
效果:
@Controller
public class testController {
@RequestMapping("/hello")
public User newuser()
{
User user=new User();
user.setAge(1);
user.setUsername("222");
user.setEmail("3333");
return user;
}
}
3 @Getter
注解 同样的是标记在类上是给这个类自动创建Getter方法,标记在属性上就是给这个属性创建Getter方法
@Getter
public class User implements Serializable {
private int age;
private String username;
private String email;
}
@Controller
public class testController {
@RequestMapping("/hello")
public User newuser()
{
User user=new User();
user.getAge();
user.getEmail();
user.getUsername();
return user;
}
}
标记在 属性上
public class User implements Serializable {
@Getter
private int age;
private String username;
private String email;
}
4 @NonNull
用于标注非空的
public class User implements Serializable {
private int age;
private String username;
private String email;
public String fuzhi(@NonNull Pet pet)
{
this.username=pet.getName();
return this.username;
}
}
@Controller
public class testController {
@RequestMapping("/hello")
public User newuser()
{
User user=new User();
Pet pet=null;
user.fuzhi(pet);
return user;
}
}
传入一个空对象就会提示 is marked non-null but is null
如果不使用注解的话就需要if判断参数是否为空,为空就throw抛出异常
5 @Cleanup
自动关闭相关的流对象,调用其close方法
@Cleanup Reader fileReader =
new FileReader(".\\src\\main\\java\\com\\cauchy6317\\common\\Cleanup\\ForCleanupExample1.txt");
6 @EqualsAndHashCode
1 这个注解会生成equal(Object other)和hashcode()方法 并且它会默认使用非静态 非瞬态属性
2 它可以通过参数exclude 排除一些属性
3 可以通过参数of 指定仅使用哪些属性
4 它默认仅使用该类中定义的属性并且不会调用父类的方法
这样就有可能会造成一个问题比如:
@Data
public class User implements Serializable {
private int age;
}
@Data
public class Customer extends User {
private String name;
}
@Controller
public class testController {
@RequestMapping("/getcustomer")
public void compareobject()
{
Customer customer=new Customer();
customer.setAge(11);
customer.setName("zy");
Customer customer1=new Customer();
customer1.setAge(22);
customer1.setName("zy");
System.out.println(customer.equals(customer1));
}
}
这样的输出结果是 true 这显然是不对的
所以这里 我们应该使用@EqualAndHashCode(callsuper=true) --这表示使用子类equal的时候会调用父类的equal方法和hashcode方法
注意这里如果这个类没有任何的父类 的情况下使用了@ EuqalAndHashCode(callsuper=true) 会编译报错 提示
Generating equals/hashCode with a supercall to java.lang.Object is pointless.
7 @NoArgsConstructor
表示生成一个 无参构造器,如果使用了@NoArgsConstructor(force = true) 将会将类中的所有final方法初始化为 0/false/null
@Data
@NoArgsConstructor(force = true)
public class Customer extends User {
private String name;
private final String email;
private int code;
private boolean flag;
}
@Controller
public class testController {
@RequestMapping("/getcustomer")
public void compareobject()
{
Customer customer=new Customer();
customer.setAge(11);
System.out.println("final属性初始化了 Email="+customer.getEmail());
System.out.println("final属性初始化了 Code="+customer.getCode());
System.out.println("final属性初始化了 flag="+customer.isFlag());
}
}
final属性初始化了 Email=null
final属性初始化了 Code=0
final属性初始化了 flag=false
8 @RequiredArgsConstructor
会对每一个类的特殊标注属性 生成一个有参构造函数, ,这里如果不需要对外提供构造函数可以使用 @RequiredArgsConstructor(staticName="of") 生成私有构造函数
例如:
@Data
@RequiredArgsConstructor
public class Customer extends User {
private final String email;
private final int age;
private Date date;
}
@Controller
public class testController {
@RequestMapping("/getcustomer")
public void compareobject()
{
// Customer customer=new Customer();
Customer customer=new Customer("3333",11);
customer.setAge(11);
System.out.println("final属性初始化了 Email="+customer.getEmail());
}
}
这里 final 标记的属性是必须要被初始化的,所以这里生成了相关构造函数,但是date属性可以不被初始化,所以没有相关构造函数
@Data
@RequiredArgsConstructor(staticName = "of")
public class Customer extends User {
private final String email;
private final int age;
private Date date;
}
如果标记上 staticname="of" 属性 ,那么就会生成私有的构造函数
@Data
@RequiredArgsConstructor(staticName = "of")
public class Customer extends User {
private final String email;
private final int age;
private Date date;
public static Customer getCustomer()
{
return new Customer("1111",11);
}
}
@Controller
public class testController {
@RequestMapping("/getcustomer")
public void compareobject()
{
// Customer customer=new Customer();
// Customer customer=new Customer("3333",11);
Customer customer=Customer.getCustomer();
customer.setAge(11);
System.out.println("tostring之后得对象=="+customer.toString());
}
}
9 @AllArgsConstructor
为类创建一个包含所有属性的构造函数
@Data
@AllArgsConstructor
public class Customer extends User {
private String email;
private final int age;
private Date date;
}
@Controller
public class testController {
@RequestMapping("/getcustomer")
public void compareobject()
{
// Customer customer=new Customer();
// Customer customer=new Customer("3333",11);
Customer customer=new Customer("333",22, new Date());
customer.setAge(11);
System.out.println("tostring之后得对象=="+customer.toString());
}
}
10 ToString()
打印父类的 toString() @ToString(callSuper=true)
包含重复的字段(比如子类和父类) @ToString(includeFieldNames=true)
包含一些字段 @ToString.Include(name = "some other name")
排除一下字段 @ToString.Exclude(name = "some other name")
lombok还有一些 方法,这里就不写了
比如 @synchronized 就是锁定到字段上
synchronized是线程安全中一个重要的关键字,它是一种同步锁,主要用来保证在同一个时刻,只有一个线程可以执行某个方法或者某段代码块。一般使用synchronized去锁住代码块,而不是方法,因为锁住代码块效率更高。
@synchronized是synchronized方法修饰符的更安全的变体。与一样synchronized,注释只能在静态方法和实例方法上使用。它的操作类似于synchronized关键字,但是它锁定在不同的对象上。关键字锁定在上this,但注释锁定在名为的字段上$ lock,该字段是私有的。
如果该字段不存在,则会为您创建。如果对static方法进行注释,则注释将锁定在名为的静态字段上$ LOCK
如果需要,可以自己创建这些锁。在$ lock和$ LOCK领域会当然不会,如果你已经自己原创生成的。您还可以通过将其指定为@Synchronized注释的参数来选择锁定另一个字段。在此用法变型中,不会自动创建字段,并且您必须自己明确创建它们,否则会发出错误。
@log 跟spring注释差不多
官网
https://projectlombok.org/features/all