[JAVA] Record 🎥 | Record를 DTO로 사용하는 이유

2025. 11. 24. 18:39·✏️공부/💡JAVA
728x90
반응형

[JAVA] Record 🎥 

Record를 DTO로 사용하는 이유


1️⃣ Record

Record는 Java 16에서 정식 도입된 새로운 형태의 클래스입니다.

데이터를 단순히 저장하고 전달하기 위한 용도로 설계되어 불변(Immutable) 특성을 기본으로 가집니다.

 

✅ 주요 특징

  • 모든 필드는 `final`이며, 객체 생성 후 값 변경 불가
    • 즉, 불변 객체 → 내부 필드값 불변성 보장 → 유지보수 이점
  • 컴파일 시 자동으로 다음 메서드 생성
    → `constructor`, `getter`, `equals()`, `hashCode()`, `toString()`
  • 보일러플레이트 코드 제거 (코드 간결성↑, 유지보수성↑)
  • 스레드 안전성 확보 (불변 객체이므로 동시 접근 안전)
public record MemberDto(String name, String email {}

2️⃣ DTO vs Record

항목 DTO Record
불변성 개발자가 직접 `final` 선언 필요 기본적으로 불변
코드 양 보일러플레이트 코드 많음 매우 간결함
생성자 직접 작성 자동 생성
메서드 직접 작성 (`getter`, `equals`, `hashCode`, `toString`) 자동 생성
사용 목적 계층 간 데이터 전달 불변 데이터 전달 (DTO로 활용 가능)

[DTO]

// 기존 클래스 기반 DTO
public class MemberDto {

	private final String name;
	private final String email;

	public MemberDto(String name, String email) {
		this.name = name;
		this.email = email;
	}

	public String getName() {
		return name;
	}

	public String getEamil() {
		return email;
	}
}

+) equals(), hashCode(), toString() 등
  • 보일러플레이트 코드 많음
    • 개념 : 최소한의 수정으로 재사용성 높이는 코드
    • ex) 생성자, getter 등
  • 필드값 변경 시 코드 수정 필요
    • 모든 보일러플레이트 코드 수정 ⬇️ [age 필드 추가]
    // 기존 클래스 기반 DTO
    public class MemberDto {
    
    	private final String name;
    	private final String email;
    	private final int age;
    
    	public MemberDto(String name, String email, int age) {
    		this.name = name;
    		this.email = email;
    		this.age = age;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public String getEamil() {
    		return email;
    	}
    
    	public int getAge() {
    		return age;
    	}
    }
    
    +) equals(), hashCode(), toString() 등
    

이러한 단점을 한 번에 해결하는 [Record]

// Record. 생성자, getter, hashCode(), equals(), toString() 자동 완성
public record MemberDto(String name, String email, int age) {}

  • 생성자, `getter`, `hashCode()`, `equals()`, `toString()` 등 자동 완성
  • 즉, 보일러플레이트 코드 자동 완성

3️⃣ 사용법

📌 선언

// Record
public record MemberDto(String name, String email, int age) {}
  • 선언과 동시에 필드 정의
  • 이때, 필드값 추가 시 에러 발생
    • 예외로 `static`으로 된 정적 필드는 생성 가능
    // Record
    public record MemberDto(String name, String email, int age) {
    	private static final String value = "somthing";
    }
    
     

📌 필드 접근

Member member = new Member("윤망꼬", "test@example.com");

String name = member.name(); // 윤망꼬
String email = member.email(); // test@example.com
  • 일반 객체처럼 사용
  • 필드값 접근 시 `getName()` 형태가 아니라 `name()`으로 직접 접근

📌 메서드 재정의

public record Member(String name, String email) {
	
	@Override
	public String toString() {
		return "귀여운 " + name + "입니다.";
	}
}
  • 자동 정의 되지만, 필요한 메서드만 재정의 가능

📌 생성자

  • 생성자에서 사용하는 파라미터 = 레코드 필드
    → `this.name = name` 과 같은 초기화 로직 생략 가능
    → 파라미터 생략 가능

4️⃣ getXXX가 아닌 이유

  • record는 일반 객체의 문제점을 해결하기 위해 탄생된 것이 아니므로 독립적으로 봐야함
  • 즉, record가 일반 객체 컨벤션을 따를 필요가 없음

5️⃣ Lombok과 비교

항목 Record Lombok
의존성 JDK 16 이상 기본 제공 외부 라이브러리 필요
코드 간결성 ✅ 가장 간결 `@Data`등으로 비교적 간결
기능 데이터 전달에 초점 빌더, 로깅 등 다양한 기능 제공
유연성 낮음 (불변 고정) 높음
@Data
@AllArgsConstructer
public class MemberDto {

	private final String name;
	private final String email;

}
  • 기능적으로 `Builder`, `SLF4J` 같은 다양한 기능 제공
  • 의존성
    • 외부 라이브러리이므로 설치 필요
    • IDEA도 그에 맞는 플러그인 설치 필요
    • 레코드는 자바 정식 스펙으로 JDK 16 이상이면 됨
public record Member(String name, String email) {}
  • 간결성 좋음
  • 의존성
    • 자바 정식 스펙으로 JDK 16 이상이면 됨

📌 정리
Record → 간결하고 의존성 없는 프로젝트에 적합
Lombok → 유연성과 확장 기능이 필요한 프로젝트에 적합


6️⃣ Record의 한계

  1. 상속 불가 (extends 사용 불가)
  2. 모든 필드가 `final` → 값 변경 불가능
  3. 비즈니스 로직 포함 부적절
  4. Java 16 이상에서만 사용 가능
  5. 확장성 부족 → 복잡한 도메인 모델에 부적합

7️⃣ Record vs VO

구분 Record VO
공통점 불변 객체, 값 기반 비교 (equals)
역할 단순 데이터 전달 도메인 내 의미 있는 값 표현
로직 포함 ❌ ✅ 비즈니스 규칙 포함 가능
사용 맥락 주로 DTO 계층 도메인 계층

 

📌 Record는 VO의 형태를 표현하기엔 적합하지만, 도메인 규칙을 포함하는 VO의 완전한 대체는 불가능 합니다.

 


8️⃣ 도메인 객체로 사용 지양

레코드 공식 문서

  • 레코드는 불변 데이터를 전달하기 위한 캐리어
  • 단순한 값의 집합을 표현하는 객체 지향적인 구성을 고민한다.
  • 개발자가 확장 가능한 동작보다는 불변의 데이터 모델링에 집중 할 수 있도록 도와준다.
  • 도메인 객체 = 데이터 + 비즈니스 로직
    → 단순히 데이터만 전달하기 위해 사용되는 record 목적성에 부합하지 않음
📌 즉, Record는 데이터만 전달하는 DTO에 적합하고, 도메인 로직이 필요한 엔터티나 VO에는 부적합합니다.

9️⃣ 요약

요약 내용
핵심 역할 불변 데이터 전달을 위한 간결한 클래스
장점 코드 간결성, 스레드 안전성, 유지보수성
한계 상속 불가, 비즈니스 로직 부적합
적합한 용도 DTO, 단순 데이터 구조체

 

 

 

 

728x90
반응형

'✏️공부 > 💡JAVA' 카테고리의 다른 글

[JAVA|DB] 동시성과 공유 자원 🗂️ | 꼬이지 않게 관리하는 법  (0) 2025.11.13
[JAVA] Lombok & Validation 정리 | 필수 어노테이션 가이드 📖 | @Getter / @Setter | @NoArgsConstructor / @AllArgsConstructor / @RequiredArgsConstructor  (0) 2025.09.21
[JAVA] ⚙️ 자료구조 : Heap | 간단 정리 및 삽입•삭제 과정 💬  (5) 2025.08.21
[JAVA] ⚙️ 자료구조 : Tree & Binary Search Tree 🌲 | 트리 순회 | 간단 정리 및 비교 💬  (0) 2025.08.21
[JAVA] ⚙️ 자료 구조 : Stack / Queue / Deque | 간단 비교 및 정리 💬  (0) 2025.08.21
'✏️공부/💡JAVA' 카테고리의 다른 글
  • [JAVA|DB] 동시성과 공유 자원 🗂️ | 꼬이지 않게 관리하는 법
  • [JAVA] Lombok & Validation 정리 | 필수 어노테이션 가이드 📖 | @Getter / @Setter | @NoArgsConstructor / @AllArgsConstructor / @RequiredArgsConstructor
  • [JAVA] ⚙️ 자료구조 : Heap | 간단 정리 및 삽입•삭제 과정 💬
  • [JAVA] ⚙️ 자료구조 : Tree & Binary Search Tree 🌲 | 트리 순회 | 간단 정리 및 비교 💬
망꼬누나
망꼬누나
공부한 내용을 정리하는 공간입니다.
  • 망꼬누나
    망꼬누나의 개발 공부
    망꼬누나
  • 전체
    오늘
    어제
    • 분류 전체보기 (165)
      • ℹ️ 정보 및 실습 (19)
        • ☑️ Git & GitHub (8)
        • ☑️ 프로젝트 (6)
        • ☑️ 회고 및 후기 (5)
      • 🛠 CS (1)
      • 💻코딩 (88)
        • 💡Baekjoon (17)
        • 💡Programmers (71)
      • ✏️공부 (48)
        • 💡OS (1)
        • 💡Network (6)
        • 💡SpringBoot (9)
        • 💡JAVA (21)
        • 💡SQL (1)
        • 💡DB (2)
        • ☁️ Cloud (4)
        • 💡알고리즘 (4)
      • 📌 자격증 (6)
        • 📝정보처리기사 (3)
        • 📝SQLD (3)
  • 블로그 메뉴

    • 홈
    • github
  • 나의 GitHub Contribution 그래프
    Loading data ...
  • 인기 글

  • 태그

    자바
    알고리즘
    github
    프로그래머스
    map
    Java
    트랜잭션
    Set
    AWS
    GIT
    S3
    코딩테스트
    프로그래머스 #JAVA
    자료구조
    baekjoon
    데브코스
    Stream
    네트워크
    동시성제어
    백엔드
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.5
망꼬누나
[JAVA] Record 🎥 | Record를 DTO로 사용하는 이유
상단으로

티스토리툴바