Java/Grammar

[Java 문법] @Builder

annovation 2025. 3. 19. 08:50

@Builder

✅ @Builder란?

생성자나 Setter를 사용하지 않고, 체인 형식으로 객체를 생성하는 패턴

객체가 불변(Immutable)하도록 설계 가능

필요한 값만 선택적으로 설정 가능


예제

📍 기존 방식 : 생성자 사용

public class User {
    private String name;
    private int age;
    
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

User user = new User("Alice", 25);

 

🚨 문제점

✔ 매개변수 순서를 기억해야 함

✔ 필드를 선택적으로 설정하기 어려움

✔ 코드 가독성이 떨어짐


📍 @Builder 적용 방식

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class User {
    private String name;
    private int age;
}

// 객체 생성
User user = User.builder()
        .name("Alice")
        .age(25)
        .build();

 

장점

✔ 매개변수 순서를 신경 쓰지 않아도 됨

✔ 필요하지 않은 필드는 설정하지 않아도 됨

✔ 불변 객체(Immutable Object)를 쉽게 만들 수 있음


🔎 불변 객체(Immutable Object)란?

https://annovation.tistory.com/158


내부 동작

User 클래스에서 @Builder를 사용하면 Lombok이 내부적으로 아래와 같은 빌더 클래스를 자동 생성합니다.

public class User {
    private String name;
    private int age;

    // Lombok이 생성하는 내부 빌더 클래스
    public static class UserBuilder {
        private String name;
        private int age;

        public UserBuilder name(String name) {
            this.name = name;
            return this;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        public User build() {
            return new User(name, age);
        }
    }

    public static UserBuilder builder() {
        return new UserBuilder();
    }
}

 

💡 User.builder() 호출 시, UserBuilder 인스턴스가 반환됨

💡 build() 메서드 호출 시, 최종적으로 User 객체가 생성됨


특징

1️⃣ @Builder는 기본 생성자를 자동으로 만들지 않음

기본 생성자가 필요한 경우, @NoArgsConstructor 추가

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor // 기본 생성자 추가
@Builder
public class User {
    private String name;
    private int age;
}

2️⃣ @Builder는 final 필드와 함께 사용 가능

final 필드는 한 번만 초기화 가능하며, 빌더 패턴과 함께 불변 객체를 만들기 좋음

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class User {
    private final String name;
    private final int age;
}

 

💡 빌더 패턴은 불변 객체(Immutable Object)를 만들기에 적합!


3️⃣ @Builder.Default를 사용해야 기본값 유지

@Builder를 사용하면 기본값이 무시되므로, 기본값이 필요한 경우 @Builder.Default를 사용해야 함

import lombok.Builder;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
@Builder
public class User {
    private String name;

    @Builder.Default
    private List<String> hobbies = new ArrayList<>(); // 기본값 유지
}

 

💡 @Builder.Default가 없으면 hobbies가 null이 될 수 있음


4️⃣ @Builder와 @Builder(toBuilder = true) 차이

📍 toBuilder = true 옵션

기존 객체에서 일부 값만 변경하고 새로운 객체를 만들 때 사용

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder(toBuilder = true)
public class User {
    private String name;
    private int age;
}

// 기존 객체에서 일부 값만 변경
User user1 = User.builder().name("Alice").age(25).build();
User user2 = user1.toBuilder().age(30).build();

System.out.println(user1.getName()); // Alice
System.out.println(user1.getAge());  // 25

System.out.println(user2.getName()); // Alice  (변경하지 않음)
System.out.println(user2.getAge());  // 30     (변경됨)

출처

OpenAI ChatGPT (https://openai.com)

반응형