본문으로 바로가기

@Data 어노테이션, Lombok에 대하여

category Programing/JAVA 2023. 6. 2. 10:33
반응형

@Data는 Project Lombok 라이브러리에서 제공하는 어노테이션이며, 클래스에 선언될 때 해당 클래스에 대해 getter, setter, equals, hashCode, toString 등의 메소드를 자동으로 생성해줍니다. 이를 통해 반복적인 보일러플레이트 코드를 줄이고 코드의 가독성을 높일 수 있습니다.

예를 들어, 다음과 같이 @Data 어노테이션을 사용하는 경우를 보겠습니다.

import lombok.Data;

@Data
public class User {
	private String name;
	private String email;
}



위 코드는 Lombok의 @Data 어노테이션을 사용하였으므로, User 클래스는 자동으로 getName(), setName(), getEmail(), setEmail(), equals(), hashCode(), toString() 등의 메소드를 갖게 됩니다.

그러나 이와 같은 기능을 Lombok 없이 구현하려면 아래와 같이 모든 메소드를 직접 작성해야 합니다.

public class User {
    private String name;
    private String email;

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

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

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
반응형



위와 같이 @Data 어노테이션을 사용하면 코드의 양을 크게 줄일 수 있으며, 불필요한 중복을 피하고 코드의 가독성을 높일 수 있습니다. 그러나 Lombok은 컴파일 시점에 코드를 생성하기 때문에, 개발 도구나 빌드 도구가 Lombok을 지원해야 합니다. 또한, Lombok이 생성하는 메소드가 클래스의 동작에 영향을 미칠 수 있으므로 주의가 필요합니다.

 

Lombok 라이브러리

Lombok 라이브러리는 다음과 같은 다양한 어노테이션을 제공하며, 이를 통해 여러 가지 반복적인 코드 작성을 줄일 수 있습니다.

@Getter / @Setter: 클래스의 필드에 대한 getter 및 setter 메소드를 자동으로 생성합니다.

@ToString: toString() 메소드를 자동으로 생성합니다. 생성된 toString() 메소드는 클래스의 필드를 문자열 형태로 출력합니다.

@EqualsAndHashCode: equals() 및 hashCode() 메소드를 자동으로 생성합니다.

@NoArgsConstructor: 매개변수가 없는 기본 생성자를 자동으로 생성합니다.

@AllArgsConstructor: 모든 필드를 매개변수로 받는 생성자를 자동으로 생성합니다.

@RequiredArgsConstructor: final 또는 @NonNull이 붙은 필드만을 매개변수로 받는 생성자를 자동으로 생성합니다.

@Builder: 빌더 패턴을 구현한 클래스를 자동으로 생성합니다. 이를 통해 객체 생성 시 유연한 인스턴스 설정이 가능합니다.

@Slf4j / @Log 등: 로깅을 위한 로거 객체를 자동으로 생성합니다. 이 어노테이션은 로깅 프레임워크별로 다양하게 제공됩니다.

@Cleanup: 자원 해제를 자동으로 처리하는 코드를 생성합니다. 주로 스트림, 소켓 등의 자원을 안전하게 해제하기 위해 사용됩니다.

@Synchronized: 동기화된(synchronized) 메소드를 생성합니다. 내부적으로는 메소드 내부에 잠금 객체를 생성하여 사용하므로, 기존의 Java의 synchronized 키워드를 사용하는 것보다 안전성이 높습니다.

이와 같은 기능들을 Lombok을 통해 제공받아서, 반복적인 코드를 줄이고 코드의 가독성을 높일 수 있습니다. 다만, Lombok은 컴파일 시점에 코드를 생성하기 때문에, IDE가 Lombok을 지원하거나 별도의 Lombok 플러그인 설치가 필요할 수 있습니다. 또한, Lombok을 사용함으로써 생기는 부작용이나 한계점도 있으므로, 그런 점들을 충분히 고려한 후에 사용하는 것이 좋습니다.

 

아래는, Lombok을 사용했을때와 사용하지 않았을 때의 코드를 비교해서 보여드리겠습니다.

@NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor 어노테이션

Lombok 사용:

import lombok.*;

@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class User {
    @NonNull
    private String name;
    private int age;
}

Lombok 미사용:

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

    public User() {
    }

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

    public User(String name) {
        if (name == null) {
            throw new NullPointerException("name is marked non-null but is null");
        }
        this.name = name;
    }

    // getter, setter 등도 필요하다면 추가로 구현해야 합니다...
}

@Builder 어노테이션

Lombok 사용:

import lombok.Builder;

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

Lombok 미사용:

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

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

    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);
        }
    }

    // 사용 예: User user = new User.UserBuilder().name("John").age(30).build();
}

@Slf4j 어노테이션

Lombok 사용:

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class User {
    public void someMethod() {
        log.info("This is an info message");
    }
}

Lombok 미사용:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class User {
    private static final Logger log = LoggerFactory.getLogger(User.class);

    public void someMethod() {
        log.info("This is an info message");
    }
}

@Cleanup 어노테이션

Lombok 사용:

import lombok.Cleanup;
import java.io.*;

public class Example {
    public void method() {
        try {
            @Cleanup InputStream in = new FileInputStream("file.txt");
            // 파일 처리 로직...
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Lombok 미사용:

import java.io.*;

public class Example {
    public void method() {
        InputStream in = null;
        try {
            in = new FileInputStream("file.txt");
            // 파일 처리 로직...
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

@Synchronized 어노테이션

Lombok 사용:

import lombok.Synchronized;

public class Example {
    private final Object readLock = new Object();

    @Synchronized("readLock")
    public void method() {
        // 동기화 블록 내에서 처리 로직...
    }
}

Lombok 미사용:

public class Example {
    private final Object readLock = new Object();

    public void method() {
        synchronized (readLock) {
            // 동기화 블록 내에서 처리 로직...
        }
    }
}

 

이렇게 Lombok을 사용하면 getter, setter, 생성자, toString, equals, hashCode 등의 메소드 작성, 빌더 패턴 구현, 로깅 객체 생성, 자원 해제 처리, 동기화 처리 등 다양한 부분에서 많은 편의를 제공하며, 반복적인 코드 작성을 줄일 수 있습니다. 다만 Lombok을 사용하면서도 그 내부 동작 방식을 이해하고, 필요한 경우에만 적절히 사용하는 것이 중요합니다.

 

Random Photo

반응형