카테고리 없음

[Spring/Lombok] Constructor 3형제에 대해 알아보자‼️

데브승찬 2025. 2. 12. 21:26

 

오늘은 Lombok에서 생성자 생성에 대한 기능을 제공해주는 어노테이션인

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor에 대해 알아 보려고 한다.

 

우리가 좋아하는 치킨을 예제로, Lombok 없이 작성했을 때와 비교하면서 알아보도록 하겠다.

 

@NoArgsConstructor

먼저 @NoArgsConstructor는 파라미터가 없는 기본 생성자를 만드는데 사용하는 어노테이션이다.

 

예제를 통해 알아보자

@Getter
@NoArgsConstructor //Lombok 사용
public class Chicken {
    private String name;
    private int price;
}

 

여기선 이 Lombok 덕분에 기본 생성자가 자동으로 생성된다.  즉, new Chicken(); 처럼 매개변수 없이 객체를 생성할 수 있게 되는 것이다.

 

Lombok 없이 작성할 경우

@Getter
public class Chicken {
    private String name;
    private int price;

    public Chicken() { // 기본 생성자를 수동으로 생성함
    }
}

 

이렇게 Lombok을 사용하지 않으면 직접 기본 생성자를 작성해 줘야 한다.

 

※주의사항※

이 어노테이션을 클래스에 붙이면, 기본 생성자가 public으로 생성되기 때문에, 굳이 외부에 생성을 열어둘 필요가 없으면 막는것이 좋다.

@NoArgsConstructor(access = AccessLevel.PROTECTED)  이런식으로 접근 권한을 최소화하는 것을 권장한다.

 

 

@RequiredArgsConstructor

이 @RequiredArgsConstructor는 final이나 @NonNull인 필드값만 파라미터로 받는 생성자를 만들어준다.

 

예제를 통해 알아보자

 

@Getter
@RequiredArgsConstructor //Lombok 사용
public class Chicken {
    private final String name;
    private final int price;
}

 

이렇게 하면 name과 price를 매개변수로 받는 생성자가 자동으로 생성된다.

Chicken chicken = new Chicken("뿌링클", 23000);

 

하지만 만약 private String brand; 같은 final이 없는 필드는 생성자의 매개변수에 포함이 되지 않는다.

 

Lombok 없이 작성할 경우

 

@Getter
public class Chicken {
    private final String name;
    private final int price;

    public Chicken(String name, int price) { // 필드를 받는 생성자를 직접 생성함
        this.name = name;
        this.price = price;
    }
}

 

이렇게 Lombok 없이 사용하면 필수 필드만 받는 생성자를 직접 작성해야 한다.

 

 

@AllArgsConstructor

이 @AllArgsConstructor는 클래스의 모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성한다.

 

예제를 통해 알아보자

 

@Getter
@AllArgsConstructor //Lombok 사용
public class Chicken {
    private String name;
    private int price;
    private String brand;
}

 

이렇게 하면 모든 필드를 초기화하는 생성자가 자동으로 생성된다.

Chicken chicken = new Chicken("뿌링클", 23000, "bhc");

 

이렇게 name, price, brand 까지 한번에 초기화 가능하다. 

 

Lombok 없이 작성할 경우

 

@Getter
public class Chicken {
    private String name;
    private int price;
    private String brand;

    public Chicken(String name, int price, String brand) { // 모든 필드를 받는 생성자를 직접 생성함
        this.name = name;
        this.price = price;
        this.brand = brand;
    }
}

 

이렇게 Lombok을 사용하지 않으면 직접 모든 필드를 받는 생성자를 만들어야 한다.

 

※@AllArgsConstructor 사용을 지양하자❓※

문제점

 

알아본 바로 @AllArgsConstructor 어노테이션은 모든 필드를 받는 생성자를 만들어준다.  

그러나 이 경우에 생성자 사용의 문제점인 같은 타입에 매개변수 (name, brand) 를 서로 바꿔 입력했을 때 발생하는 문제다. 

@Getter
@AllArgsConstructor
public class Chicken {
    private String name;
    private int price;
    private String brand;
}

 

위 코드에서 생성된 생성자는 다음과 같다.

 public Chicken(String name, int price, String brand) {
        this.name = name;
        this.price = price;
        this.brand = brand;
    }

 

여기서 필드 순서를 바꾸면?

@Getter
@AllArgsConstructor
public class Chicken {
    private String name;
    private String brand;
    private int price;
}

 

이렇게 변경하면 기존 코드에서 Chicken chicken = new Chicken("뿌링클", 23000, "bhc"); 같은 부분이 컴파일 오류 없이도 잘못된 값으로 생성될 수 있다. 

 

해결책

 

해결방법은 상황에 따라 다를 수 있음

 

1. @Builder 패턴 사용

  • 가독성이 좋음
  • 필드 순서 변경에도 안전함
  • 필요한 필드만 설정 가능함
  • 유지보수와 확장성이 뛰어남

2. @RequiredArgsConstructor 사용

  • 필드 순서 변경에 안전함
  • 불필요한 필드까지 강제 초기화 하는 문제를 해결할 수 있음

 

 

마무리

오늘은 생성자 생성시 자주 사용하는 어노테이션들에 대해 알아보았다.

사용하면서 무슨 역할들을 하는지 궁금하고 알고 쓰는 습관을 위해 정리 해봤는데 도움이 많이 된것같다.