Record에 대해서 알아보자
저는 DTO를 만들 때 Record 클래스를 사용하고 있습니다. 그렇다면, 왜 Record 클래스를 사용할까요?
이번 포스팅에서는 그 이유를 알아보겠습니다.
Record 클래스가 등장한 배경
DTO를 불변 객체로 만들기 위해, 기존에는 클래스의 필드에 final을 붙여 불변성을 유지했습니다. 또한, 필드 값을 가져오기 위해 getter 메서드를 따로 작성해야 했습니다.
하지만 서비스를 개발하다 보면 DTO를 자주 만들어야 하는데, 이러한 과정이 상당히 번거롭습니다. 이러한 불편함을 해소하기 위해 Java 16에서 Record 클래스가 도입되었습니다.
Record 클래스가 자동으로 해주는 것
예를 들어, 아래와 같은 Example 클래스가 있다고 가정해 보겠습니다.
public record Example(String ex1, String ex2) {}
전체 필드를 초기화하는 생성자
public Example(String ex1, String ex2) {
this.ex1 = ex1;
this.ex2 = ex2;
}
→ 기존 클래스에서는 직접 작성해야 했지만, record를 사용하면 자동으로 생성됩니다.
Getter 메서드 제공
record에서는 필드명과 동일한 메서드가 자동 생성되므로, 아래처럼 사용할 수 있습니다.
public class Main {
public static void main(String[] args) {
// Example 레코드 객체 생성
Example example = new Example("Hello", "Record");
// getter 메서드 호출 (record는 필드명과 동일한 메서드 자동 생성)
System.out.println("ex1: " + example.ex1()); // Hello
System.out.println("ex2: " + example.ex2()); // Record
}
}
equals(), hashCode(), toString() 자동 생성
객체 비교와 해시 값 계산, 문자열 변환을 위한 메서드를 자동으로 구현해 줍니다.
모든 필드가 final로 선언
필드가 자동으로 final이 되어 불변성이 보장됩니다.
Record 클래스에는 조금 특이한 생성자가 있습니다. 바로 컴팩트 생성자입니다.
컴팩트 생성자(Compact Constructor)
oracle에서는 컴팩트 생성자에 대해서 아래와 같이 설명합니다.
레코드의 생성자가 단순히 private 필드를 초기화하는 것 이상을 수행하도록 하려면, 사용자 정의 생성자를 정의할 수 있습니다. 그러나 클래스의 생성자와 달리, 레코드의 생성자는 형식적인 매개변수 목록을 가지지 않습니다. 이를 축약 생성자(compact constructor)라고 합니다.
컴팩트 생성자는 validation을 할 수 있으며 파라미터를 작성하지 않아도 됩니다.
public record Example(String ex1, String ex2) {
// Compact Constructor (컴팩트 생성자)
public Example{
Objects.requireNonNull(ex1, "ex1은 null일 수 없습니다.");
Objects.requireNonNull(ex2, "ex1은 null일 수 없습니다.");
}
}
컴팩트 생성자가 작성된 경우, 생성자 호출 → 컴팩트 생성자를 통한 검증 → 인스턴스 생성 및 반환 순으로 진행됩니다.
지금까지 Record에 대해서 알아보았습니다. 감사합니다.