ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 16. Record Class
    BackEnd/Java 2024. 12. 8. 09:00
    반응형

    Record Class

      Java 14 preview, Java 16 정식으로 출시된 기능으로 데이터 전달을 위해 등장한 클래스입니다.

     

      다음은 데이터 전달을 위한 DTO 클래스입니다.

    import java.time.LocalDate;
    import java.util.Objects;
    
    public final class FruitDto {
      private final String name; // 과일 이름
      private final int price; // 과일 가격
      private final LocalDate date; // 과일 입고 일자
      
      public FruitDto(String name, int price, LocalDate date) {
        this.name = name;
        this.price = price;
        this.date = date;
      }
      
      public String name() {
        return name;
      }
      
      public int price() {
        return price;
      }
      
      public LocalDate date() {
        return date;
      }
      
      @Override
      public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FruitDto fruitDto = (FruitDto) o;
        return price == fruitDto.price && Objects.equals(name, fruitDto.name) && Objects.equals(date, fruitDto.date);
      }
      
      @Override
      public int hashCode() {
        return Objects.hash(name, price, date);
      }
      
      @Override
      public String toString() {
        return "FruitDto[" +
            "name='" + name + '\'' +
            ", price=" + price +
            ", date=" + date +
            ']';
      }
    }
    • class에 final이 선언되어 있어서 다른 클래스가 상속 받지 못합니다.
    • private final 필드만 선언되어 있습니다.
    • 모든 private final 필드에 대해 생성자가 존재합니다.
    • 클래스가 갖고 있는 모든 필드에 접근할 수 있는 메소드가 있고, 메소드의 이름은 필드의 이름과 동일합니다.
    • equals() / hashCode() / toString()이 존재합니다.

     

      개발을 하다보면 이러한 데이터 전달 객체 (DTO)를 꽤 많이 만들게 됩니다. 다음은 위의 FruitDto 클래스를 Record 클래스로 구현한 코드입니다.

    public record FruitDtoV2(
        String name, // 컴포넌트(Component)
        int price,
        LocalDate date
    ) {
    }
    • 일반적인 클래스와 다르게 ()로 시작합니다.
    • () 안에는 Record 클래스가 갖고 있을 필드들을 선언합니다.
    • FruitDtoV2 Record 클래스는 FruitDto 클래스와 완전히 동일합니다.
    • 다른 클래스가 상속 받을 수 없습니다.
    • 컴포넌트에 대한 private final 필드가 자동으로 생성됩니다.
    • name, price, date를 받아 필드에 값을 할당하는 생성자도 자동으로 생성됩니다.
    • 필드에 접근할 수 있는 name(), price(), date() getter가 자동으로 생성됩니다.
    • equals() / hashCode() / toString() 자동으로 생성됩니다.

     

    Record Class 특징

    • 다른 클래스를 상속 받을 수 없습니다.
    • 인터페이스는 구현이 가능합니다.
    • static 필드, 함수, 인스턴스 함수 등을 만들 수 있습니다. 단, 인스턴스 필드는 만들 수 없습니다.
    • 자동 생성되는 메소드들을 직접 재정의 할 수 있습니다.
    • 값을 검증하려면 일반적인 생성자 대신 compact constructor를 사용할 수 있습니다.
    public record FruitDtoV2(
        String name,
        int price,
        LocalDate date
    ) {
      private static final double DISCOUNT_RATE = 0.3;
      
      public int getDiscountPrice() {
        return (int) (price * (1.0 - DISCOUNT_RATE));
      }
      
      // compact constructor
      public FruitDtoV2 {
        System.out.println("생성자 호출!");
        // 값 검증
        if (price < 0) {
          // price = 0; // this를 사용할 수 없습니다. 값을 변경하려면 일반적인 필드를 사용합니다.
          throw new IllegalArgumentException("과일의 가격은 양수입니다!");
        }
      }
      
      public String name() {
        return "[재정의] " + this.name;
      }
    }

      compact constructor: 매개변수를 전혀 받지 않아 문법적으로 간결합니다. 단, 필드에 값을 할당할 시 this를 사용할 수 없습니다.

     

    Record Class와 스프링 부트

    • Jackson 2.12.0 이상(Spring Boot 2.5.x 이상)에서 Record 클래스 사용이 가능합니다.
    • HTTP 쿼리 파라미터와 바디 모두 잘 적용됩니다.
    • Record 클래스를 사용하면 lombok의 어노테이션 없이 데이터 전달 클래스를 생성할 수 있습니다.
    반응형

    'BackEnd > Java' 카테고리의 다른 글

    Java 12-17. 주요 변경 내용  (0) 2024.12.10
    Java 17. Sealed Class  (1) 2024.12.09
    Java 16. instanceof Pattern Matching  (0) 2024.12.08
    Java 15. Text Block  (0) 2024.12.07
    Java 14. Switch Expression  (0) 2024.12.07

    댓글

Designed by Tistory.