欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Lombok為啥這么牛逼?SpringBoot和IDEA官方都要支持它

 更新時(shí)間:2020年12月24日 10:30:02   投稿:mrr  
Lombok是一款Java代碼功能增強(qiáng)庫(kù),在Github上已有9.8k+Star。這篇文章主要介紹了Lombok為啥這么牛逼?SpringBoot和IDEA官方都要支持它,需要的朋友可以參考下

最近 IDEA 2020最后一個(gè)版本發(fā)布了 ,已經(jīng)內(nèi)置了Lombok插件,SpringBoot 2.1.x之后的版本也在Starter中內(nèi)置了Lombok依賴。為什么他們都要支持Lombok呢?今天我來講講Lombok的使用,看看它有何神奇之處!

Lombok簡(jiǎn)介

Lombok是一款Java代碼功能增強(qiáng)庫(kù),在Github上已有9.8k+Star。它會(huì)自動(dòng)集成到你的編輯器和構(gòu)建工具中,從而使你的Java代碼更加生動(dòng)有趣。通過Lombok的注解,你可以不用再寫getter、setter、equals等方法,Lombok將在編譯時(shí)為你自動(dòng)生成。

Lombok集成

首先我們需要在IDEA中安裝好Lombok插件,如果你使用的是最新版IDEA 2020.3,則Lombok插件已經(jīng)內(nèi)置,無需安裝。

之后在項(xiàng)目的pom.xml文件中添加Lombok依賴,SpringBoot 2.1.x版本后無需指定Lombok版本,SpringBoot在 spring-boot-dependencies 中已經(jīng)內(nèi)置。

<!--lombok依賴-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
</dependency>

Lombok使用

Lombok中有很多注解,這些注解使得我們可以更加方便的編寫Java代碼,下面介紹下這些注解的使用。

val

使用val注解可以取代任意類型作為局部變量,這樣我們就不用寫復(fù)雜的ArrayList和Map.Entry類型了,具體例子如下。

/**
 * Created by macro on 2020/12/16.
 */
public class ValExample {

 public static void example() {
 //val代替ArrayList<String>和String類型
 val example = new ArrayList<String>();
 example.add("Hello World!");
 val foo = example.get(0);
 System.out.println(foo.toLowerCase());
 }

 public static void example2() {
 //val代替Map.Entry<Integer,String>類型
 val map = new HashMap<Integer, String>();
 map.put(0, "zero");
 map.put(5, "five");
 for (val entry : map.entrySet()) {
  System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
 }
 }

 public static void main(String[] args) {
 example();
 example2();
 }
}

當(dāng)我們使用了val注解后,Lombok會(huì)從局部變量的初始化表達(dá)式推斷出具體類型,編譯后會(huì)生成如下代碼。

public class ValExample {
 public ValExample() {
 }

 public static void example() {
 ArrayList<String> example = new ArrayList();
 example.add("Hello World!");
 String foo = (String)example.get(0);
 System.out.println(foo.toLowerCase());
 }

 public static void example2() {
 HashMap<Integer, String> map = new HashMap();
 map.put(0, "zero");
 map.put(5, "five");
 Iterator var1 = map.entrySet().iterator();

 while(var1.hasNext()) {
  Entry<Integer, String> entry = (Entry)var1.next();
  System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
 }

 }
}

@NonNull

在方法上使用@NonNull注解可以做非空判斷,如果傳入空值的話會(huì)直接拋出NullPointerException。

/**
 * Created by macro on 2020/12/16.
 */
public class NonNullExample {
 private String name;
 public NonNullExample(@NonNull String name){
 this.name = name;
 }

 public static void main(String[] args) {
 new NonNullExample("test");
 //會(huì)拋出NullPointerException
 new NonNullExample(null);
 }
}

編譯后會(huì)在構(gòu)造器中添加非空判斷,具體代碼如下。

public class NonNullExample {
 private String name;

 public NonNullExample(@NonNull String name) {
 if (name == null) {
  throw new NullPointerException("name is marked non-null but is null");
 } else {
  this.name = name;
 }
 }

 public static void main(String[] args) {
 new NonNullExample("test");
 new NonNullExample((String)null);
 }
}

@Cleanup

當(dāng)我們?cè)贘ava中使用資源時(shí),不可避免地需要在使用后關(guān)閉資源。使用@Cleanup注解可以自動(dòng)關(guān)閉資源。

/**
 * Created by macro on 2020/12/16.
 */
public class CleanupExample {
 public static void main(String[] args) throws IOException {
 String inStr = "Hello World!";
 //使用輸入輸出流自動(dòng)關(guān)閉,無需編寫try catch和調(diào)用close()方法
 @Cleanup ByteArrayInputStream in = new ByteArrayInputStream(inStr.getBytes("UTF-8"));
 @Cleanup ByteArrayOutputStream out = new ByteArrayOutputStream();
 byte[] b = new byte[1024];
 while (true) {
  int r = in.read(b);
  if (r == -1) break;
  out.write(b, 0, r);
 }
 String outStr = out.toString("UTF-8");
 System.out.println(outStr);
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class CleanupExample {
 public CleanupExample() {
 }

 public static void main(String[] args) throws IOException {
 String inStr = "Hello World!";
 ByteArrayInputStream in = new ByteArrayInputStream(inStr.getBytes("UTF-8"));

 try {
  ByteArrayOutputStream out = new ByteArrayOutputStream();

  try {
  byte[] b = new byte[1024];

  while(true) {
   int r = in.read(b);
   if (r == -1) {
   String outStr = out.toString("UTF-8");
   System.out.println(outStr);
   return;
   }

   out.write(b, 0, r);
  }
  } finally {
  if (Collections.singletonList(out).get(0) != null) {
   out.close();
  }

  }
 } finally {
  if (Collections.singletonList(in).get(0) != null) {
  in.close();
  }

 }
 }
}

@Getter/@Setter

有了@Getter/@Setter注解,我們?cè)僖膊挥镁帉慻etter/setter方法了。試想下之前即使我們使用IDEA自動(dòng)生成getter/setter方法,如果類屬性的類型和名稱改了,又要重新生成getter/setter方法也是一件很麻煩的事情。

/**
 * Created by macro on 2020/12/17.
 */
public class GetterSetterExample {
 @Getter
 @Setter
 private String name;
 @Getter
 @Setter(AccessLevel.PROTECTED)
 private Integer age;

 public static void main(String[] args) {
 GetterSetterExample example = new GetterSetterExample();
 example.setName("test");
 example.setAge(20);
 System.out.printf("name:%s age:%d",example.getName(),example.getAge());
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class GetterSetterExample {
 private String name;
 private Integer age;

 public GetterSetterExample() {
 }

 public String getName() {
 return this.name;
 }

 public void setName(final String name) {
 this.name = name;
 }

 public Integer getAge() {
 return this.age;
 }

 protected void setAge(final Integer age) {
 this.age = age;
 }
}

@ToString

把所有類屬性都編寫到toString方法中方便打印日志,是一件多么枯燥無味的事情。使用@ToString注解可以自動(dòng)生成toString方法,默認(rèn)會(huì)包含所有類屬性,使用@ToString.Exclude注解可以排除屬性的生成。

/**
 * Created by macro on 2020/12/17.
 */
@ToString
public class ToStringExample {
 @ToString.Exclude
 private Long id;
 private String name;
 private Integer age;
 public ToStringExample(Long id,String name,Integer age){
 this.id =id;
 this.name = name;
 this.age = age;
 }

 public static void main(String[] args) {
 ToStringExample example = new ToStringExample(1L,"test",20);
 //自動(dòng)實(shí)現(xiàn)toString方法,輸出ToStringExample(name=test, age=20)
 System.out.println(example);
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class ToStringExample {
 private Long id;
 private String name;
 private Integer age;

 public ToStringExample(Long id, String name, Integer age) {
 this.id = id;
 this.name = name;
 this.age = age;
 }

 public String toString() {
 return "ToStringExample(name=" + this.name + ", age=" + this.age + ")";
 }
}

@EqualsAndHashCode

使用@EqualsAndHashCode注解可以自動(dòng)生成hashCode和equals方法,默認(rèn)包含所有類屬性,使用@EqualsAndHashCode.Exclude可以排除屬性的生成。

/**
 * Created by macro on 2020/12/17.
 */
@Getter
@Setter
@EqualsAndHashCode
public class EqualsAndHashCodeExample {
 private Long id;
 @EqualsAndHashCode.Exclude
 private String name;
 @EqualsAndHashCode.Exclude
 private Integer age;

 public static void main(String[] args) {
 EqualsAndHashCodeExample example1 = new EqualsAndHashCodeExample();
 example1.setId(1L);
 example1.setName("test");
 example1.setAge(20);
 EqualsAndHashCodeExample example2 = new EqualsAndHashCodeExample();
 example2.setId(1L);
 //equals方法只對(duì)比id,返回true
 System.out.println(example1.equals(example2));
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class EqualsAndHashCodeExample {
 private Long id;
 private String name;
 private Integer age;

 public EqualsAndHashCodeExample() {
 }

 public boolean equals(final Object o) {
 if (o == this) {
  return true;
 } else if (!(o instanceof EqualsAndHashCodeExample)) {
  return false;
 } else {
  EqualsAndHashCodeExample other = (EqualsAndHashCodeExample)o;
  if (!other.canEqual(this)) {
  return false;
  } else {
  Object this$id = this.getId();
  Object other$id = other.getId();
  if (this$id == null) {
   if (other$id != null) {
   return false;
   }
  } else if (!this$id.equals(other$id)) {
   return false;
  }

  return true;
  }
 }
 }

 protected boolean canEqual(final Object other) {
 return other instanceof EqualsAndHashCodeExample;
 }

 public int hashCode() {
 int PRIME = true;
 int result = 1;
 Object $id = this.getId();
 int result = result * 59 + ($id == null ? 43 : $id.hashCode());
 return result;
 }
}

@XxConstructor

使用@XxConstructor注解可以自動(dòng)生成構(gòu)造方法,有@NoArgsConstructor、@RequiredArgsConstructor和@AllArgsConstructor三個(gè)注解可以使用。

  • @NoArgsConstructor:生成無參構(gòu)造函數(shù)。
  • @RequiredArgsConstructor:生成包含必須參數(shù)的構(gòu)造函數(shù),使用@NonNull注解的類屬性為必須參數(shù)。
  • @AllArgsConstructor:生成包含所有參數(shù)的構(gòu)造函數(shù)。
/**
 * Created by macro on 2020/12/17.
 */
@NoArgsConstructor
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor
public class ConstructorExample {
 @NonNull
 private Long id;
 private String name;
 private Integer age;

 public static void main(String[] args) {
 //無參構(gòu)造器
 ConstructorExample example1 = new ConstructorExample();
 //全部參數(shù)構(gòu)造器
 ConstructorExample example2 = new ConstructorExample(1L,"test",20);
 //@NonNull注解的必須參數(shù)構(gòu)造器
 ConstructorExample example3 = ConstructorExample.of(1L);
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class ConstructorExample {
 @NonNull
 private Long id;
 private String name;
 private Integer age;

 public ConstructorExample() {
 }

 private ConstructorExample(@NonNull final Long id) {
 if (id == null) {
  throw new NullPointerException("id is marked non-null but is null");
 } else {
  this.id = id;
 }
 }

 public static ConstructorExample of(@NonNull final Long id) {
 return new ConstructorExample(id);
 }

 public ConstructorExample(@NonNull final Long id, final String name, final Integer age) {
 if (id == null) {
  throw new NullPointerException("id is marked non-null but is null");
 } else {
  this.id = id;
  this.name = name;
  this.age = age;
 }
 }
}

@Data

@Data是一個(gè)方便使用的組合注解,是@ToString、@EqualsAndHashCode、@Getter、@Setter和@RequiredArgsConstructor的組合體。

/**
 * Created by macro on 2020/12/17.
 */
@Data
public class DataExample {
 @NonNull
 private Long id;
 @EqualsAndHashCode.Exclude
 private String name;
 @EqualsAndHashCode.Exclude
 private Integer age;

 public static void main(String[] args) {
 //@RequiredArgsConstructor已生效
 DataExample example1 = new DataExample(1L);
 //@Getter @Setter已生效
 example1.setName("test");
 example1.setAge(20);
 //@ToString已生效
 System.out.println(example1);
 DataExample example2 = new DataExample(1L);
 //@EqualsAndHashCode已生效
 System.out.println(example1.equals(example2));
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class DataExample {
 @NonNull
 private Long id;
 private String name;
 private Integer age;

 public DataExample(@NonNull final Long id) {
 if (id == null) {
  throw new NullPointerException("id is marked non-null but is null");
 } else {
  this.id = id;
 }
 }

 @NonNull
 public Long getId() {
 return this.id;
 }

 public String getName() {
 return this.name;
 }

 public Integer getAge() {
 return this.age;
 }

 public void setId(@NonNull final Long id) {
 if (id == null) {
  throw new NullPointerException("id is marked non-null but is null");
 } else {
  this.id = id;
 }
 }

 public void setName(final String name) {
 this.name = name;
 }

 public void setAge(final Integer age) {
 this.age = age;
 }

 public boolean equals(final Object o) {
 if (o == this) {
  return true;
 } else if (!(o instanceof DataExample)) {
  return false;
 } else {
  DataExample other = (DataExample)o;
  if (!other.canEqual(this)) {
  return false;
  } else {
  Object this$id = this.getId();
  Object other$id = other.getId();
  if (this$id == null) {
   if (other$id != null) {
   return false;
   }
  } else if (!this$id.equals(other$id)) {
   return false;
  }

  return true;
  }
 }
 }

 protected boolean canEqual(final Object other) {
 return other instanceof DataExample;
 }

 public int hashCode() {
 int PRIME = true;
 int result = 1;
 Object $id = this.getId();
 int result = result * 59 + ($id == null ? 43 : $id.hashCode());
 return result;
 }

 public String toString() {
 return "DataExample(id=" + this.getId() + ", name=" + this.getName() + ", age=" + this.getAge() + ")";
 }
}

@Value

使用@Value注解可以把類聲明為不可變的,聲明后此類相當(dāng)于final類,無法被繼承,其屬性也會(huì)變成final屬性。

/**
 * Created by macro on 2020/12/17.
 */
@Value
public class ValueExample {
 private Long id;
 private String name;
 private Integer age;

 public static void main(String[] args) {
 //只能使用全參構(gòu)造器
 ValueExample example = new ValueExample(1L,"test",20);
 // example.setName("andy") //沒有生成setter方法,會(huì)報(bào)錯(cuò)
 // example.name="andy" //字段被設(shè)置為final類型,會(huì)報(bào)錯(cuò)
 }
}

編譯后Lombok會(huì)生成如下代碼。

public final class ValueExample {
 private final Long id;
 private final String name;
 private final Integer age;

 public static void main(String[] args) {
 new ValueExample(1L, "test", 20);
 }

 public ValueExample(final Long id, final String name, final Integer age) {
 this.id = id;
 this.name = name;
 this.age = age;
 }

 public Long getId() {
 return this.id;
 }

 public String getName() {
 return this.name;
 }

 public Integer getAge() {
 return this.age;
 }
}

@Builder

使用@Builder注解可以通過建造者模式來創(chuàng)建對(duì)象,建造者模式加鏈?zhǔn)秸{(diào)用,創(chuàng)建對(duì)象太方便了!

/**
 * Created by macro on 2020/12/17.
 */
@Builder
@ToString
public class BuilderExample {
 private Long id;
 private String name;
 private Integer age;

 public static void main(String[] args) {
 BuilderExample example = BuilderExample.builder()
  .id(1L)
  .name("test")
  .age(20)
  .build();
 System.out.println(example);
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class BuilderExample {
 private Long id;
 private String name;
 private Integer age;

 BuilderExample(final Long id, final String name, final Integer age) {
 this.id = id;
 this.name = name;
 this.age = age;
 }

 public static BuilderExample.BuilderExampleBuilder builder() {
 return new BuilderExample.BuilderExampleBuilder();
 }

 public String toString() {
 return "BuilderExample(id=" + this.id + ", name=" + this.name + ", age=" + this.age + ")";
 }

 public static class BuilderExampleBuilder {
 private Long id;
 private String name;
 private Integer age;

 BuilderExampleBuilder() {
 }

 public BuilderExample.BuilderExampleBuilder id(final Long id) {
  this.id = id;
  return this;
 }

 public BuilderExample.BuilderExampleBuilder name(final String name) {
  this.name = name;
  return this;
 }

 public BuilderExample.BuilderExampleBuilder age(final Integer age) {
  this.age = age;
  return this;
 }

 public BuilderExample build() {
  return new BuilderExample(this.id, this.name, this.age);
 }

 public String toString() {
  return "BuilderExample.BuilderExampleBuilder(id=" + this.id + ", name=" + this.name + ", age=" + this.age + ")";
 }
 }
}

@SneakyThrows

還在手動(dòng)捕獲并拋出異常?使用@SneakyThrows注解自動(dòng)實(shí)現(xiàn)試試!

/**
 * Created by macro on 2020/12/17.
 */
public class SneakyThrowsExample {

 //自動(dòng)拋出異常,無需處理
 @SneakyThrows(UnsupportedEncodingException.class)
 public static byte[] str2byte(String str){
 return str.getBytes("UTF-8");
 }

 public static void main(String[] args) {
 String str = "Hello World!";
 System.out.println(str2byte(str).length);
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class SneakyThrowsExample {
 public SneakyThrowsExample() {
 }

 public static byte[] str2byte(String str) {
 try {
  return str.getBytes("UTF-8");
 } catch (UnsupportedEncodingException var2) {
  throw var2;
 }
 }
}

@Synchronized

當(dāng)我們?cè)诙鄠€(gè)線程中訪問同一資源時(shí),往往會(huì)出現(xiàn)線程安全問題,以前我們往往使用synchronized關(guān)鍵字修飾方法來實(shí)現(xiàn)同步訪問。使用@Synchronized注解同樣可以實(shí)現(xiàn)同步訪問。

package com.macro.mall.tiny.example;

import lombok.*;

/**
 * Created by macro on 2020/12/17.
 */
@Data
public class SynchronizedExample {
 @NonNull
 private Integer count;

 @Synchronized
 @SneakyThrows
 public void reduceCount(Integer id) {
 if (count > 0) {
  Thread.sleep(500);
  count--;
  System.out.println(String.format("thread-%d count:%d", id, count));
 }
 }

 public static void main(String[] args) {
 //添加@Synchronized三個(gè)線程可以同步調(diào)用reduceCount方法
 SynchronizedExample example = new SynchronizedExample(20);
 new ReduceThread(1, example).start();
 new ReduceThread(2, example).start();
 new ReduceThread(3, example).start();
 }


 @RequiredArgsConstructor
 static class ReduceThread extends Thread {
 @NonNull
 private Integer id;
 @NonNull
 private SynchronizedExample example;

 @Override
 public void run() {
  while (example.getCount() > 0) {
  example.reduceCount(id);
  }
 }
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class SynchronizedExample {
 private final Object $lock = new Object[0];
 @NonNull
 private Integer count;

 public void reduceCount(Integer id) {
 try {
  synchronized(this.$lock) {
  if (this.count > 0) {
   Thread.sleep(500L);
   Integer var3 = this.count;
   Integer var4 = this.count = this.count - 1;
   System.out.println(String.format("thread-%d count:%d", id, this.count));
  }

  }
 } catch (Throwable var7) {
  throw var7;
 }
 }
}

@With

使用@With注解可以實(shí)現(xiàn)對(duì)原對(duì)象進(jìn)行克隆,并改變其一個(gè)屬性,使用時(shí)需要指定全參構(gòu)造方法。

@With
@AllArgsConstructor
public class WithExample {
 private Long id;
 private String name;
 private Integer age;

 public static void main(String[] args) {
 WithExample example1 = new WithExample(1L, "test", 20);
 WithExample example2 = example1.withAge(22);
 //將原對(duì)象進(jìn)行clone并設(shè)置age,返回false
 System.out.println(example1.equals(example2));
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class WithExample {
 private Long id;
 private String name;
 private Integer age;

 public WithExample withId(final Long id) {
 return this.id == id ? this : new WithExample(id, this.name, this.age);
 }

 public WithExample withName(final String name) {
 return this.name == name ? this : new WithExample(this.id, name, this.age);
 }

 public WithExample withAge(final Integer age) {
 return this.age == age ? this : new WithExample(this.id, this.name, age);
 }

 public WithExample(final Long id, final String name, final Integer age) {
 this.id = id;
 this.name = name;
 this.age = age;
 }
}

@Getter(lazy=true)

當(dāng)我們獲取某一個(gè)屬性比較消耗資源時(shí),可以給@Getter添加 lazy=true 屬性實(shí)現(xiàn)懶加載,會(huì)生成Double Check Lock 樣板代碼對(duì)屬性進(jìn)行懶加載。

/**
 * Created by macro on 2020/12/17.
 */
public class GetterLazyExample {
 @Getter(lazy = true)
 private final double[] cached = expensive();

 private double[] expensive() {
 double[] result = new double[1000000];
 for (int i = 0; i < result.length; i++) {
  result[i] = Math.asin(i);
 }
 return result;
 }

 public static void main(String[] args) {
 //使用Double Check Lock 樣板代碼對(duì)屬性進(jìn)行懶加載
 GetterLazyExample example = new GetterLazyExample();
 System.out.println(example.getCached().length);
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class GetterLazyExample {
 private final AtomicReference<Object> cached = new AtomicReference();

 public GetterLazyExample() {
 }

 private double[] expensive() {
 double[] result = new double[1000000];

 for(int i = 0; i < result.length; ++i) {
  result[i] = Math.asin((double)i);
 }

 return result;
 }

 public double[] getCached() {
 Object value = this.cached.get();
 if (value == null) {
  synchronized(this.cached) {
  value = this.cached.get();
  if (value == null) {
   double[] actualValue = this.expensive();
   value = actualValue == null ? this.cached : actualValue;
   this.cached.set(value);
  }
  }
 }

 return (double[])((double[])(value == this.cached ? null : value));
 }
}

@Log

使用@Log注解,可以直接生成日志對(duì)象log,通過log對(duì)象可以直接打印日志。

/**
 * Created by macro on 2020/12/17.
 */
@Log
public class LogExample {
 public static void main(String[] args) {
 log.info("level info");
 log.warning("level warning");
 log.severe("level severe");
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class LogExample {
 private static final Logger log = Logger.getLogger(LogExample.class.getName());

 public LogExample() {
 }

 public static void main(String[] args) {
 log.info("level info");
 log.warning("level warning");
 log.severe("level severe");
 }
}

@Slf4j

使用Lombok生成日志對(duì)象時(shí),根據(jù)使用日志實(shí)現(xiàn)的不同,有多種注解可以使用。比如@Log、@Log4j、@Log4j2、@Slf4j等。

/**
 * Created by macro on 2020/12/17.
 */
@Slf4j
public class LogSlf4jExample {
 public static void main(String[] args) {
 log.info("level:{}","info");
 log.warn("level:{}","warn");
 log.error("level:{}", "error");
 }
}

編譯后Lombok會(huì)生成如下代碼。

public class LogSlf4jExample {
 private static final Logger log = LoggerFactory.getLogger(LogSlf4jExample.class);

 public LogSlf4jExample() {
 }

 public static void main(String[] args) {
 log.info("level:{}", "info");
 log.warn("level:{}", "warn");
 log.error("level:{}", "error");
 }
}

Lombok原理

如果IDEA不安裝Lombok插件的話,我們打開使用Lombok的項(xiàng)目是無法通過編譯的。裝了以后IDEA才會(huì)提示我們Lombok為我們生成的方法和屬性。

使用了@Data注解以后,查看類結(jié)構(gòu)可以發(fā)現(xiàn)getter、setter、toString等方法。

打開target目錄下的 .class 文件,我們可以看到Lombok為我們生成的代碼,可見Lombok是通過解析注解,然后在編譯時(shí)生成代碼來實(shí)現(xiàn)Java代碼的功能增強(qiáng)的。

 

參考資料

官方文檔:https://projectlombok.org/features/all

項(xiàng)目源碼地址

https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-lombok

到此這篇關(guān)于Lombok為啥這么牛逼?SpringBoot和IDEA官方都要支持它的文章就介紹到這了,更多相關(guān)Lombok SpringBoot和IDEA內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中RabbitMQ高級(jí)應(yīng)用

    java中RabbitMQ高級(jí)應(yīng)用

    本文主要介紹了java中RabbitMQ高級(jí)應(yīng)用,中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 使用@TransactionalEventListener監(jiān)聽事務(wù)教程

    使用@TransactionalEventListener監(jiān)聽事務(wù)教程

    這篇文章主要介紹了使用@TransactionalEventListener監(jiān)聽事務(wù)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼

    java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼

    java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼,需要的朋友可以參考一下
    2013-05-05
  • MybatisPlusInterceptor依賴變紅如何解決,無法識(shí)別問題

    MybatisPlusInterceptor依賴變紅如何解決,無法識(shí)別問題

    這篇文章主要介紹了MybatisPlusInterceptor依賴變紅如何解決,無法識(shí)別問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java如何使用interrupt()終止線程

    Java如何使用interrupt()終止線程

    這篇文章主要介紹了Java如何使用interrupt()終止線程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Spring Boot3.x自動(dòng)配置不生效的排查與解決方法(IDEA 文件夾命名導(dǎo)致的問題)

    Spring Boot3.x自動(dòng)配置不生效的排查與解決方法(IDEA 文件夾命名導(dǎo)致的問題)

    在SpringBoot多模塊項(xiàng)目中,自動(dòng)配置類未生效的問題通常源于文件路徑錯(cuò)誤,通過檢查和修正AutoConfiguration.imports文件的實(shí)際路徑,可以解決自動(dòng)配置不生效的問題,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java常見啟動(dòng)命令-jar、-server和-cp詳細(xì)比較

    Java常見啟動(dòng)命令-jar、-server和-cp詳細(xì)比較

    這篇文章主要給大家介紹了關(guān)于Java常見啟動(dòng)命令-jar、-server和-cp詳細(xì)比較的相關(guān)資料,該文總結(jié)了常歸的jar包的啟動(dòng)方式,并分析各種啟動(dòng)方式的區(qū)別,需要的朋友可以參考下
    2023-07-07
  • Java-Io-RandomAccessFile任意位置讀寫數(shù)據(jù)的操作小結(jié)

    Java-Io-RandomAccessFile任意位置讀寫數(shù)據(jù)的操作小結(jié)

    RandomAccessFile類支持隨機(jī)訪問方式,可以跳轉(zhuǎn)到文件的任意位置讀寫數(shù)據(jù),這個(gè)類在文件隨機(jī)讀取時(shí)有很大的優(yōu)勢(shì),可利用多線程完成對(duì)一個(gè)大文件的讀寫,本文給大家介紹Java-Io-RandomAccessFile(任意位置讀寫數(shù)據(jù))的相關(guān)知識(shí),需要的朋友可以參考下
    2022-05-05
  • 深入了解volatile和Java內(nèi)存模型

    深入了解volatile和Java內(nèi)存模型

    在本篇文章當(dāng)中,主要給大家深入介紹Volatile關(guān)鍵字和Java內(nèi)存模型。在文章當(dāng)中首先先介紹volatile的作用和Java內(nèi)存模型,然后層層遞進(jìn)介紹實(shí)現(xiàn)這些的具體原理、JVM底層是如何實(shí)現(xiàn)volatile的和JVM實(shí)現(xiàn)的匯編代碼以及CPU內(nèi)部結(jié)構(gòu),感興趣的可以了解一下
    2022-08-08
  • springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能(上)

    springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能(上)

    這篇文章主要為大家詳細(xì)介紹了springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能,比較基礎(chǔ)的學(xué)習(xí)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07

最新評(píng)論