본문 바로가기
개발

[Lombok] @data

by angeloper 2023. 7. 19.
반응형

자바 개발자들은 각종 생성자, 메서드, 핸들러 등의 반복적인 코드 작성으로 시간을 내어야 하는 경우가 많습니다. 이러한 단점을 해결하기 위해 롬복(Lombok) 라이브러리를 도입하여 코드를 간소화할 수 있습니다. 이번 글에서는 롬복의 핵심 어노테이션 중 하나인 @Data 어노테이션에 대해 설명하겠습니다. 이 글에서는 @Data 어노테이션의 기능과 사용법, 추가 옵션, 그리고 장단점을 다룰 것입니다.

사용법

롬복의 @Data 어노테이션은 클래스의 필드를 자동으로 활용한 기본 생성자, 게터(getter), 세터(setter), equals(), hashCode(), 그리고 toString() 메서드를 생성해 주는 강력한 기능을 제공합니다. 이를 통해 개발자들은 코드를 효율적으로 작성할 수 있습니다. 이 어노테이션은 클래스 수준에서 사용되며 불필요한 코드를 줄일 수 있어 가독성과 유지 관리성이 향상됩니다.

@Data 어노테이션을 사용하는 방법은 매우 간단합니다. 필드(멤버 변수)를 가진 클래스에 @Data 어노테이션을 추가만 하면 됩니다. 롬복은 자동으로 생성자 및 기타 메서드들을 생성해 줍니다. 예를 들어, 다음과 같이 사용할 수 있습니다.

import lombok.Data;

@Data
public class Customer {
    private final String firstName;
    private final String lastName;
    private String email;
    private int age;
}

롬복은 위 예제 코드에서 생성자, 게터, 세터, equals(), hashCode(), 그리고 toString() 메서드를 각각 필드에 대해 자동 생성해 줍니다.

public class Customer {
    private final String firstName;
    private final String lastName;
    private String email;
    private int age;

    public Customer(final String firstName, final String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public String getEmail() {
        return this.email;
    }

    public int getAge() {
        return this.age;
    }

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

    public void setAge(final int age) {
        this.age = age;
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Customer)) {
            return false;
        } else {
            Customer other = (Customer)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (this.getAge() != other.getAge()) {
                return false;
            } else {
                label49: {
                    Object this$firstName = this.getFirstName();
                    Object other$firstName = other.getFirstName();
                    if (this$firstName == null) {
                        if (other$firstName == null) {
                            break label49;
                        }
                    } else if (this$firstName.equals(other$firstName)) {
                        break label49;
                    }

                    return false;
                }

                Object this$lastName = this.getLastName();
                Object other$lastName = other.getLastName();
                if (this$lastName == null) {
                    if (other$lastName != null) {
                        return false;
                    }
                } else if (!this$lastName.equals(other$lastName)) {
                    return false;
                }

                Object this$email = this.getEmail();
                Object other$email = other.getEmail();
                if (this$email == null) {
                    if (other$email != null) {
                        return false;
                    }
                } else if (!this$email.equals(other$email)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Customer;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        result = result * 59 + this.getAge();
        Object $firstName = this.getFirstName();
        result = result * 59 + ($firstName == null ? 43 : $firstName.hashCode());
        Object $lastName = this.getLastName();
        result = result * 59 + ($lastName == null ? 43 : $lastName.hashCode());
        Object $email = this.getEmail();
        result = result * 59 + ($email == null ? 43 : $email.hashCode());
        return result;
    }

    public String toString() {
        String var10000 = this.getFirstName();
        return "Customer(firstName=" + var10000 + ", lastName=" + this.getLastName() + ", email=" + this.getEmail() + ", age=" + this.getAge() + ")";
    }
}

@data의 추가옵션

  •  staticConstructor : 이 추가옵션은 @RequiredArgsConstructor의 추가옵션인 staticName과 동일한 기능을 하는 추가 옵션입니다. 하기 예제를 확인하시면, of라는 메서드가 추가되어 있는 부분을 확인하실 수 있습니다.
import lombok.Data;

@Data(staticConstructor = "of")
public class Customer {
    private final String firstName;
    private final String lastName;
    private String email;
    private int age;
}

위 코드로 할 시에 다음과 같은 코드로 변환되어 나옵니다.

public class Customer {
    private final String firstName;
    private final String lastName;
    private String email;
    private int age;

    private Customer(final String firstName, final String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public static Customer of(final String firstName, final String lastName) {
        return new Customer(firstName, lastName);
    }

    public String getFirstName() {
        return this.firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public String getEmail() {
        return this.email;
    }

    public int getAge() {
        return this.age;
    }

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

    public void setAge(final int age) {
        this.age = age;
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Customer)) {
            return false;
        } else {
            Customer other = (Customer)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (this.getAge() != other.getAge()) {
                return false;
            } else {
                label49: {
                    Object this$firstName = this.getFirstName();
                    Object other$firstName = other.getFirstName();
                    if (this$firstName == null) {
                        if (other$firstName == null) {
                            break label49;
                        }
                    } else if (this$firstName.equals(other$firstName)) {
                        break label49;
                    }

                    return false;
                }

                Object this$lastName = this.getLastName();
                Object other$lastName = other.getLastName();
                if (this$lastName == null) {
                    if (other$lastName != null) {
                        return false;
                    }
                } else if (!this$lastName.equals(other$lastName)) {
                    return false;
                }

                Object this$email = this.getEmail();
                Object other$email = other.getEmail();
                if (this$email == null) {
                    if (other$email != null) {
                        return false;
                    }
                } else if (!this$email.equals(other$email)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Customer;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        result = result * 59 + this.getAge();
        Object $firstName = this.getFirstName();
        result = result * 59 + ($firstName == null ? 43 : $firstName.hashCode());
        Object $lastName = this.getLastName();
        result = result * 59 + ($lastName == null ? 43 : $lastName.hashCode());
        Object $email = this.getEmail();
        result = result * 59 + ($email == null ? 43 : $email.hashCode());
        return result;
    }

    public String toString() {
        String var10000 = this.getFirstName();
        return "Customer(firstName=" + var10000 + ", lastName=" + this.getLastName() + ", email=" + this.getEmail() + ", age=" + this.getAge() + ")";
    }
}

@data의 장점

  • 코드 간결성: 더 짧은 코드로 간결하고 가독성 높은 클래스를 작성할 수 있습니다.
  • 유지 보수성 향상: 롬복이 자동으로 필드와 관련된 메서드를 생성해 주기 때문에 클래스 수정이 용이해집니다.
  • 중복 코드 제거: 코드의 중복이 줄어들면서 일관된 구현을 가질 수 있습니다.
  • 생산성 향상: 반복적인 작업을 줄여 개발 시간을 단축하고 개발자의 생산성을 향상합니다.

@data의 단점

  • 런타임 의존성: 롬복 라이브러리를 사용하게 되면 프로젝트에 새로운 의존성이 생겨 프로젝트를 배포할 때 포함해야 합니다.
  • 가독성 감소: 롬복 어노테이션에 익숙하지 않으면 학습 곡선이 있을 수 있으며 코드 이해에 어려움이 생길 수 있습니다.
  • IDE 및 빌드 도구 호환성: 롬복과 일부 IDE 및 빌드 도구 사이에 결합 문제가 발생할 수 있어, 이를 해결할 수 있는 추가 설정이 필요할 수도 있습니다.

결론

롬복의 @Data 어노테이션은 클래스에 대한 생성자, 게터, 세터, equals(), hashCode(), 그리고 toString() 메서드를 자동으로 생성해 주어 개발자들의 작업을 용이하게 합니다. 무엇보다 이를 통해 코드의 간결성과 가독성이 크게 향상됩니다. 하지만 롬복 라이브러리의 의존성 및 호환성 문제 등의 단점을 고려하며 사용하도록 합니다.

이 글을 통해 @Data 어노테이션의 기능과 사용법, 장단점에 대해 알아보았습니다. 프로젝트의 요구 사항에 따라 롬복의 사용 여부를 결정할 수 있습니다.

 
반응형