Java의 record
는 Java 16에서 도입된 기능으로, 데이터를 간결하고 명확하게 표현하기 위해 설계된 불변(immutable) 데이터 클래스를 만드는 데 사용됩니다. 주로 데이터를 저장하고 전달하는 용도로 사용되며, DTO(Data Transfer Object)와 같은 단순한 데이터 구조를 쉽게 정의할 수 있습니다. record
는 기본적으로 생성자, getter
, equals
, hashCode
, toString
메서드를 자동으로 생성하여 코드의 간결성을 높입니다.
Record 예시:
public record Person(String name, int age) {}
위 코드에서 Person
클래스는 생성자와 필드 접근 메서드들이 자동으로 제공되므로, 매우 간결하게 데이터를 표현할 수 있습니다.
1) 클래스로 정의한 DTO 예시:
public class UserDto {
private final String name;
private final int age;
public UserDto(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserDto userDto = (UserDto) o;
return age == userDto.age && Objects.equals(name, userDto.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "UserDto{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
위 코드는 UserDto
객체를 정의하기 위해 생성자, getter, equals
, hashCode
, toString
메서드를 직접 작성해야 합니다. 이러한 반복적인 작업이 많아지면 유지보수에도 부담이 생길 수 있습니다.
2) Record로 정의한 DTO 예시:
public record UserDto(String name, int age) {}
record
를 사용하면, 위의 클래스에서 작성했던 모든 메서드와 기능을 한 줄로 정의할 수 있습니다. record
는 컴파일 시 자동으로 생성자와 getter
, equals
, hashCode
, toString
메서드를 제공하기 때문에 코드가 훨씬 간결해집니다.
특성 | Class 기반 DTO | Record 기반 DTO |
---|---|---|
코드 작성 | 수동으로 메서드 작성 | 자동으로 메서드 생성 |
불변성 | 기본적으로 가변적 | 기본적으로 불변적 |
초기화 및 추가 로직 | 복잡한 초기화 가능 | 간단한 초기화에 적합 |
상속 | 가능 | 불가능 |
record
는 선언만으로 필요한 메서드가 자동으로 제공되기 때문에, 반복적인 코드 작성을 줄이고 코드의 가독성을 높여줍니다.record
는 기본적으로 불변성을 유지합니다. 한 번 생성된 객체의 필드 값이 변경되지 않기 때문에 멀티스레드 환경에서 안전하게 사용할 수 있습니다. 반면, 클래스로 정의한 DTO는 가변적으로 필드를 수정할 수 있어 유연하게 사용할 수 있습니다.record
는 단순한 데이터 전송에 주로 사용됩니다.Record를 사용할 때:
Class를 사용할 때:
record
는 상속을 지원하지 않으므로, 상속 구조가 필요한 경우 클래스가 적합합니다.record
는 불변이므로, 객체 생성 후 필드를 수정할 수 없습니다. 불변성을 유지하면서 객체의 필드를 수정해야 하는 경우, record
대신 클래스를 사용하는 것이 더 좋습니다.record
생성자에서 필드 검증 로직을 포함할 수 있지만, 복잡한 검증이 필요할 때는 클래스를 사용하는 것이 더 자연스러울 수 있습니다.record
는 상속을 지원하지 않기 때문에 상속을 통해 공통 기능을 구현하고자 한다면 클래스를 사용해야 합니다. 대신 컴포지션(composition)을 고려해 볼 수 있습니다.record
는 간결함이 장점이지만, 너무 많은 필드를 담고 있다면 오히려 가독성이 떨어질 수 있습니다. record
의 사용 목적이 명확한 경우에만 사용하는 것이 좋습니다.DTO와 record
는 상황에 따라 적절히 선택해야 합니다. 데이터의 불변성과 간결성이 중요하고, 추가적인 로직이 필요 없는 경우에는 record
를 사용하는 것이 유리합니다. 반면, 데이터 수정이 필요하거나, 복잡한 초기화와 검증 로직이 필요한 DTO에는 클래스를 사용하는 것이 더 적합합니다.
결국, record
도 DTO의 일종으로, 클래스와 record
를 어떤 상황에서 사용할지 구분하는 것이 중요합니다. 처음 record
를 사용하는 사람이라면, 이를 간단한 데이터 전달 목적으로 사용하고, 복잡한 로직이 포함된 DTO는 클래스로 구현하는 것이 좋습니다. 프로젝트의 특성과 요구사항에 맞게 record와 클래스를 적절히 선택하여 효율적이고 유지보수 가능한 코드를 작성합시다.