본문 바로가기
Java

Java - Lombok 주의사항 1 @AllArgsConstructor @RequiredArgsConstructor

by 오늘부터개발시작 2022. 9. 18.

 

 

 

 

 

 

Lombok 사용시 주의사항

지난 시간에는 Lombok에서 주로 사용하는 기능들에 대해서 알아보았다. Lombok을 잘 사용하면 참 편리하지만 Java가 그렇게 단순한 언어는 아니다보니 무분별하게 사용하면 예기치 못한 문제를 마주칠 수 있다. 이번 시간에는 Lombok을 사용할 때 반드시 알고 주의해야할 사항들에 대해서 알아보도록하겠다. 오늘은 @AllArgsConstructor 와 @RequiredArgsConstructor을 사용할 때 주의할 점에 대해서 알아보겠다. Lombok의 기본에 대해서 궁금하다면 이전 글을 참고하길 바란다.

 

https://today-devstart.tistory.com/34

 

Java - Lombok이란?

Boilerplate 코드들 Java를 사용하기 위해서는 엄청나게 많은 Boilerplate 코드들을 작성하게 된다. 가장 기본적인 변수에 접근하기 위해서도 getter를 선언해야 한다. 실제 코드는 몇 줄 안되는 것 같은

obv-cloud.com

 

@AllArgsConstructor

@AllArgsConsturctor를 사용하면 클래스의 모든 필드로 생성자를 만들어 매우 편리하게 사용할 수 있지만 사용하지 않는 것을 추천한다.

아래 코드처럼 @AllArgsConstructor는 클래스에 필드가 선언된 순서대로 인자를 받는 생성자를 자동으로 만들어 준다. 만약 선언한 필드의 순서가 바뀌면 생성자의 인수 순서도 바뀌게 된다. 생성자는 인수 순서가 정해져있는데 어노테이션 때문에 인자의 순서가 의도치 않게 바뀌면서 예기치 못한 버그가 발생할 수 있다. 단순히 컴파일 에러가나면 다행이지만 몇일이 지난 후에야 버그를 발견하게 될 수도 있다. 어떤 문제가 생길 수 있는지 아래 예시를 통해 확인해보자.

 

예를 들어 상점의 개점, 폐점 시간을 인스턴스 멤버로 가지고 있는 Store 클래스가 있고 @AllArgsConstructor를 사용해서 생성자를 만들었다고 가정해보자.

@AllArgsConstructor
public class Store {
	private int openAt // 1;
    	private int closeAt // 2;
        
        // 자동 생성 된 생성자
        public MyClass(int openAt, int closeAt) {
		this.openAt = openAt; // 1
		this.closeAt = closeAt; // 2
	}
}

 

@AllArgsConstructor 어노테이션이 선언된 클래스를 리팩토링하다가 closeAt과 openAt의 순서가 뒤바뀌었다. 개발자는 별 생각하지 않고 지나갔겠지만 @AllArgsConstructor는 필드가 선언된 순서대로 생성자를 만들기 때문에 생성자의 인수 순서가 아래처럼 바뀌게 된다.  closeAt과 openAt의 type은 int로 동일하기 때문에 컴파일타임은 물론 런타임에서도 에러가 나지 않는다. 

@AllArgsConstructor
public class Store {
	private int closeAt; // 1
	private int openAt; // 2
    	
        public MyClass(int closeAt, int openAt) {
      		this.closeAt = closeAt; // 1
		this.openAt = openAt; //2
		
	}
}
// 오전 8시에 영업 종료하고 오후 10시에 영업 시작을 함
new Store(오전 8시, 오후 10시);

 

위 코드처럼 어딘가에서 생성자를 사용해 Store 객체를 생성할텐데 openAt이 들어가야할 자리에 closeAt이 들어가고 closeAt에는 openAt이 들어가고 있을 것이다. 배달 어플로 예를 들면 가게들이 한창 배달 주문을 받아야 할 시간에 영업 종료라고 안내가 되고 새벽에 영업중이 되는 것이다. 이처럼 전혀 예기치 못한 치명적인 버그가 발생할 수 있기 때문에 사용을 금지하는 것이다. 개발자는 나중에서야 데이터가 잘못 들어가고 있다는 것을 알겠지만 @AllArgsConstructor의 특징을 모른다면 문제를 해결하는데 많은 시간을 낭비할지도 모른다. 

@RequiredArgsConstructor

@RequiredArgsConstructor도 @AllArgsConstructor와 동일하게 생성자를 생성해주는데 사용을 금지하는 것은 아니고 필요에 따라 적절히 사용하는 것을 추천한다.

@RequiredArgsConstructor가 사용되는 대부분의 경우 의존성 주입을 위해 사용하기 때문에 @AllArgsConstructor와 같은 에러가 발생할 경우는 적다. 서비스, 컨트롤러 등에서 주로 쓰이기 때문에 해당 클래스를 객체화 할 일이 거의 없기 때문이다.

 

이 외에 @RequiredArgsConstructor는 부모를 상속하는 클래스에서는 사용하는 것을 권장하지 않는다. 왜냐면 부모에서 상속 받은 필드들은 자동으로 생성된 생성자에 추가되지 않기 때문이다. 이 경우에는 직접 생성자를 선언해서 상속 받은 필드들도 super 키워드로 의존성을 주입시켜줘야한다.