Lombok과 상속: 부모 생성자 호출의 제약사항

Lombok은 Java에서 보일러플레이트 코드를 줄여주는 유용한 라이브러리입니다. Lombok을 사용하면, 간단한 어노테이션으로 getter, setter, 생성자 등을 자동으로 생성할 수 있습니다. 그러나 Lombok을 사용할 때, 특히 상속 관계에서 부모 클래스의 생성자를 호출하는 데 몇 가지 제약이 따릅니다. 이 글에서는 이러한 제약 사항과 그 이유에 대해 설명하겠습니다.

Lombok의 생성자 어노테이션

먼저 Lombok의 주요 생성자 어노테이션에 대해 간단히 살펴보겠습니다.

  • @AllArgsConstructor: 모든 필드를 인자로 받는 생성자를 생성합니다.
  • @NoArgsConstructor: 인자가 없는 기본 생성자를 생성합니다.
  • @RequiredArgsConstructor: final이나 @NonNull 필드를 인자로 받는 생성자를 생성합니다.

이러한 어노테이션들은 클래스 내부의 생성자 코드를 자동으로 작성해 주어 편리하게 사용할 수 있습니다. 그러나 상속 관계에서는 상황이 다소 복잡해집니다.

문제 상황: 부모 생성자 호출 불가

아래 예제를 보겠습니다. Parent 클래스는 Lombok을 사용하여 생성자를 생성하고 있습니다.

@AllArgsConstructor
public class Parent {
    public String a;
    public String b;
}

Parent 클래스를 상속받는 Child 클래스는 부모 클래스의 생성자를 호출하려고 합니다.

public class Child extends Parent {
    public Child() {
        super("", ""); // 호출 불가능!
    }
}

위 코드에서 super("", "") 호출은 컴파일 오류를 발생시킵니다. 왜 이런 일이 발생할까요?

Lombok에서 부모 생성자 호출 불가 이유

Lombok 개발자가 설명한 바에 따르면, Lombok은 상속받은 클래스의 부모 생성자를 자동으로 호출하는 기능을 지원하지 않습니다. 이는 다음과 같은 이유 때문입니다:

  1. 해결(Resolution) 문제: Lombok이 호출 시점에 부모 클래스의 생성자를 찾는 것은 간단하지 않습니다. Lombok이 실행될 때, 부모 클래스는 이름으로만 참조되며, 실제 클래스와 그 생성자를 찾기 위해서는 import 문과 classpath를 사용해야 합니다. 이는 컴파일 타임에 쉽지 않은 작업입니다.
  2. 리플렉션 제한: 컴파일 시점에 리플렉션을 사용하여 생성자 목록을 가져오는 것은 불가능합니다. 런타임과 달리 컴파일 타임에는 이러한 작업이 제한됩니다.
  3. 복잡성과 오류 가능성: Lombok이 val@ExtensionMethod에서 해결 작업을 수행하는 예를 보면, 이는 복잡하고 오류가 발생하기 쉬운 작업임을 알 수 있습니다.

이러한 이유로 Lombok은 부모 클래스의 생성자를 자동으로 호출하는 기능을 제공하지 않습니다.

제약 사항

이로 인해 Lombok의 생성자 어노테이션을 사용할 때 다음과 같은 제약 사항이 생깁니다:

  1. 자식 클래스에서 Lombok 생성자 어노테이션 사용 불가: 자식 클래스에서는 Lombok의 @AllArgsConstructor와 같은 생성자 어노테이션을 사용할 수 없습니다. 부모 클래스의 생성자를 호출하는 코드를 직접 작성해야 합니다.
  2. 부모 클래스의 Lombok 생성자 호출 불가: 자식 클래스에서는 부모 클래스에 Lombok으로 생성된 생성자를 호출할 수 없습니다. 부모 클래스에 직접 정의된 생성자만 호출 가능합니다.

해결 방법

이 문제를 해결하기 위해서는 다음과 같은 방법을 사용할 수 있습니다:

  1. 부모 클래스에 직접 생성자 작성: 부모 클래스에 필요한 생성자를 Lombok이 아닌 직접 작성합니다. 이렇게 하면 자식 클래스에서 해당 생성자를 호출할 수 있습니다.
public class Parent {
    public String a;
    public String b;

    public Parent(String a, String b) {
        this.a = a;
        this.b = b;
    }
}
  1. 자식 클래스에서 생성자 직접 작성: 자식 클래스에서는 Lombok을 사용하지 않고, 부모 클래스의 생성자를 호출하는 생성자를 직접 작성합니다.
public class Child extends Parent {
    public Child() {
        super("", "");
    }
}

이와 같은 방법으로 Lombok의 제약을 극복하고, 부모 클래스의 생성자를 호출할 수 있습니다.

결론

Lombok은 매우 유용한 도구이지만, 상속 관계에서 부모 생성자를 호출하는 데는 몇 가지 제약이 있습니다. 이러한 제약을 이해하고 적절한 해결 방법을 적용하면, Lombok을 효과적으로 사용할 수 있습니다. 이 글이 Lombok과 상속 관계에서의 생성자 호출 문제를 이해하는 데 도움이 되었기를 바랍니다.

개발자 성현