-
Java 16. Record ClassBackEnd/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