IT/언어

[Java] 자주 사용되는 Lombok 어노테이션

개발자 두더지 2023. 5. 15. 21:41
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.

 

 

Lombok이란?


 어노테이션을 부여하는 것으로 Java의 상용구 코드를 쓰지 않도록 해주는 라이브러리이다. 어노테이션을 부여하는 것만으로 모든 필드에 대해서 getter, setter을 구현해주거나, 생성자를 구현해주거나한다.

 데이터 클래스의 작성이나 생성자 인젝션이 편해지므로, Spring-Boot와 매우 궁합이 좋다고 개인적으로 생각한다. 그리고 immutable 객체를 쓰고 싶을 때에도 도움이 되므로, 써보길 바란다. 

 

 

Getter, Setter


 클래스 혹은 필드에 @Getter, @Setter을 부여하면 getter, setter이 자동적으로 구현된다. 예를 들면 다음과 같은 Sample.java 코드가 있다고 가정하자.

@Getter
@Setter
public class Sample {
  private String id;
  private String name;
  private Integer age:
}

 위 코드를 컴파일하여 Sample.class를 확인하면 다음과 같다.

public class Sample {
  private String id;
  private String name;
  private Integer age:

  public String getId() {
    return this.id;
  }

  public String getName() {
    return this.name;
  }

  public Integer getAge() {
    return this.name;
  }

  public void setId(String id) {
    this.id = id;
  }

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

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

 실제로 보면 모든 필드에 대해서 getter과 setter이 구현되어 있음을 알 수 있다. 필드가 많으면 많을수록 작성하는 코드가 줄어드니까 굉장히 편리하다.

 이 예의 경우 class에 대해서 부여했지만, 모든 필드에 대해서 부여하고 싶지 않은 경우는 필요한 필드에만 부여하면 된다.

 

 

△△ ArgsConstructor(생성자)


 이것들을 어노테이션으로 작성하면 생성자가 자동적으로 생성해준다. 크게 세 종류가 있다.

  • @NoArgsConstructor : 기본 생성자를 자동 생성해준다.
  • @AllArgsConstructor : 모든 필드에 대해서 초기화 값을 인수로 하는 생성자를 생성해준다.
  • @RequiredArgsConstructor : final 필드에 대해서 초기화 값을 인수로 하는 생성자를 생성해준다.

 

RequiredArgsConstructor

 다음과 같은 Sample.java 코드가 있다고 하자.

@RequiredArgsConstructor
public class Sample {
  private final String id;
  private final String name;
  private Integer age;
}

 그럼 다음과 같은 Sample.class가 만들어진다.

public class Sample {
  private final String id;
  private final String name;
  private Integer age;

  public Sample(String id, String name) {
    this.id = id;
    this.name = name;
  }
}

 

NoArgsConstructor + AllArgsConstructor

여러 개를 부여하면 그만큼의 생성자가 생성된다. Java의 사양상, 명확히 생성자를 구현하고 있으면 기본 생성자는 구현되지 않으므로, @NoArgsConstructor도 꽤 사용된다.

@NoArgsConstructor
@AllArgsConstructor
public class Sample {
  private String id;
  private String name;
  private Integer age;
}
public class Sample {
  private String id;
  private String name;
  private Integer age;

  public Sample() {
  };

  public Sample (String id, String name, Integer age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
}

 이 조합의 경우는 MyBatis의 Entity와 궁합이 좋다.

 

 

ToString


 @ToString은 이 이름대로, toString을 구현(오버라이드)해준다. 혹은 exclude를 사용하면 대상 필드는 제외하는 것도 가능하다.

@ToString(exclude = "age")
public class Sample {
  private String id;
  private String name;
  private Integer age;
}
public class Sample {
  private String id;
  private String name;
  private Integer age;

  @Override
  public String toString() {
    return "Sample(id=" + this.id + ", name=" + this.name + ")");
  }
}

 

 

EqualsAndHashCode


 @EqualsAndHashCode도 이름 그대로 equals와 hashCode가 구현(오버라이드)된다. 왜 이 두가지가 세트로 구성되어 있는지에 대해서 말하자면, 이 둘은 구조상으로 관계가 있기 때문에 모순되면 안 되기 때문이다.

@EqualsAndHashCode
public class Sample {
  private String name;
  private int age;
}
public class Sample {
  private String name;
  private int age;

  public boolean equals(Object o) {
    if (o == this) return true;
    if (!(o instanceof Person)) return false;
    final Person other = (Person) o;
    if (!other.canEqual((Object) this)) return false;
    final Object this$name = this.name;
    final Object other$name = other.name;
    if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
    if (this.age != other.age) return false;
    return true;
  }

  public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    final Object $name = this.name;
    result = result * PRIME + ($name == null ? 0 : $name.hashCode());
    result = result * PRIME + this.age;
    return result;
  }

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

 

 

Value


 @Value를 부여하면 아래의 어노테이션이 부여되어, immutable한 객체가 된다.

  • @Getter
  • @ToString
  • @EqualsAndHashCode
  • @AllArgsConstructor
  • 클래스 및 각 필드에 final가 부여된다.
  • 각 필드의 가시성이 private가 된다.

 생성시에 생성자에 따라 값이 설정되고, 그 이후로는 값을 변경이 불가능해진다. 올바른 immutable 객체를 만들고 싶을 때에 사용하고 싶은 어노테이션이다.

 staticConstructor 옵션을 설정하면, static한 팩토리 메소드가 생성된다. 이 경우 생성자는 private로 변경되므로, 팩토리 메소드를 통하지 않으면 인스턴스를 생성할 수 없게 된다.

 

 

Data


 @Data를 부여하면 다음의 어노테이션이 부여되는 것과 동일한 상태가 된다.

  • @Getter
  • @Setter
  • @ToString
  • @EqualsAndHashCode
  • @RequiredArgsConstructor

 @Value외 비슷하게 어노테이션 기능을 정리해둔 어노테이션이다. 이것들은 단순히 Bean 클래스를 만드는 것과 비슷하다.


참고자료

https://qiita.com/supreme0110/items/391505da8f4321736421

728x90