---
# System prepended metadata

title: Lombok 使用教學

---

# Lombok 使用教學

## 前言

使用 Lombok 可以完成平常開發常使用的邏輯，可以自動完成，而不需要重複撰寫很多同樣程式碼，加快開發速度，專注商業邏輯。

## 目錄

* [介紹/基本概念](#介紹/基本概念)
  * [在 pom.xml 新增依賴](#在-pom.xml-新增依賴)
  * [新增以下檔案](#新增以下檔案)
  * [常用註解](#常用註解)
* [參考資料](#參考資料)

## 介紹/基本概念

### 在 pom.xml 新增依賴

```xml=
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
    <scope>provided</scope>
</dependency>
```

### 新增以下檔案

![Lombok](https://i.imgur.com/7Ze3t5H.jpg)

Food.java

```java=
package data;

public class Food {
    private Long id;
    
    private String name;
}
```

Main.java

```java=
package main;

public class Main {
    public static void main(String[] args) {

    }
}
```

### 常用註解

以下將以 Food.java 實作 Lombok

#### 1. @Getter / @Setter

```java=
package data;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Food {
    private Long id;

    private String name;
}
```

等同於

```java=
package data;

public class Food {
    private Long id;

    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

會自動產生 getter 和 setter ，不需要另外撰寫。

:::info
🔔 也可以將 @Getter 和 @Setter 寫在參數上，針對該參數產生 getter 和 setter
:::

#### 2. @ToString

```java=
package data;

import lombok.ToString;

@ToString
public class Food {
    private Long id;

    private String name;
}
```

等同於

```java=
package data;

public class Food {
    private Long id;

    private String name;

    @Override
    public String toString() {
        return "Food{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
```

會自動產生 toString ，不需要另外撰寫

#### 3. @EqualsAndHashCode

```java=
package data;

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class Food {
    private Long id;

    private String name;
}
```

等同於

```java=
package data;

import java.util.Objects;

public class Food {
    private Long id;

    private String name;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Food food = (Food) o;
        return Objects.equals(id, food.id) && Objects.equals(name, food.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}
```

會自動產生 equals 和 hashCode ，不需要另外撰寫

:::info
🔔 Q : 為什麼只有一個整體的 @EqualsAndHashCode 注解，而不是分開的兩個 @Equals 和 @HashCode？

A : 在 Java 中有規定，當兩個 object equals 時，它們的 hashcode 一定要相同，反之，當 hashcode 相同時，object 不一定 equals。所以 equals 和 hashcode 要一起 implement，以免發生違反 Java 規定的情形
:::

#### 4. @NoArgsConstructor

```java=
package data;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Food {
    private Long id;

    private String name;
}
```

等同於

```java=
package data;

public class Food {
    private Long id;

    private String name;

    public Food() {
    }
}
```

會自動生成一個沒有參數的 constructor

#### 5. @AllArgsConstructor

```java=
package data;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class Food {
    private Long id;

    private String name;
}
```

等同於

```java=
package data;

public class Food {
    private Long id;

    private String name;

    public Food(Long id, String name) {
        this.id = id;
        this.name = name;
    }
}
```

會自動生成一個所有參數的 constructor

:::danger
🔔 使用 @AllArgsConstructor 如果需要使用無參數建構子 constructor ，要記得補上 @NoArgsConstructor 。
:::

#### 6. @RequiredArgsConstructor

只有在第 6 節先將 id 加上 final

```java=
package data;

public class Food {
    private final Long id;

    private String name;
}
```

加上 @RequiredArgsConstructor

```java=
package data;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class Food {
    private final Long id;

    private String name;
}
```

等同於

```java=
package data;

public class Food {
    private final Long id;

    private String name;

    public Food(Long id) {
        this.id = id;
    }
}

```

會自動將 final 參數建立 constructor

#### 7. @Data

```java=
package data;

import lombok.Data;

@Data
public class Food {
    private Long id;

    private String name;
}
```

等同於

```java=
package data;

import lombok.*;

@Getter
@Setter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
public class Food {
    private Long id;

    private String name;
}
```

會自動產生 @Getter ， @Setter ， @ToString ， @EqualsAndHashCode ， @RequiredArgsConstructor ，這個註解常被使用在 Spring Data JPA 的 Entity 上

#### 8. @Value

跟 @Data 相似，但是他會把所有的變數都設成 final 的，其他的就跟 @Data 一樣 ， 少了 @Setter 功能。

會自動產生 @Getter ， @ToString ， @EqualsAndHashCode ， @RequiredArgsConstructor

#### 9. @Builder

```java=
package data;

import lombok.Builder;

@Builder
public class Food {
    private Long id;

    private String name;
}
```

Main.java

```java=
package main;

import data.Food;

public class Main {
    public static void main(String[] args) {
        Food food = Food.builder().id(1L).name("PORK").build();

    }
}

```

即可使用 builder 建立物件，不需要特別使用 set 或建構子建立。

#### 10. @Slf4j

請見[Log4J 和 Slf4J 的關係與結合使用-第 2 種方式](https://hackmd.io/7qmmjTg5QASduGNkMpmqBg)

## 參考資料

[Java - 五分鐘學會 Lombok 用法
](https://kucw.github.io/blog/2020/3/java-lombok/)
