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