record란?
- 불변 객체(필드 수정 불가)를 쉽게 생성할 수 있게 해주는 클래스 유형
- JDK14에서 preview로 등장하여 JDK16+부터 정식 스펙에 포함되었다.
record은 무엇을 할까?
- 필드 캡슐화 (private final)
- 생성자 메서드
- Getter 메서드
- equals() 메서드
- hashCode() 메서드
- toString() 메서드
record를 사용하면 위 내용들을 직접 구현하지 않아도, 자동 생성해준다.
일반 class vs record class
일반 클래스
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
record 클래스
public record Student(String name, int age) {
}
record를 사용하면, 일반 클래스에서 수동으로 작성하던 구성 요소를 자동으로 제공받을 수 있어 코드가 훨씬 간결해짐.
record 특징
1. get 메서드는 일반 클래스처럼 getName()이 아닌 필드명과 동일한 메서드 이름을 사용한다.
student.name() // student.getName() X
student.age() // student.getAge() X
2. 상속 불가
- record는 java.lang.Record를 암묵적으로 상속함
- 다른 클래스를 상속하거나 상속받는 것 불가능
- 단, 인터페이스 구현은 가능
3. 모든 필드는 final (불변성)
- 자동으로 private final 선언됨
- 생성 이후 값 변경 불가능
- → 가변성이 필요한 경우에는 부적합
record를 JPA의 Entity 클래스로 사용할 수 없는 이유
보통 JPA 엔티티는 setter나 dirty checking을 통해 필드 값의 변경이 자유롭다. 따라서, 불변성을 가진 record 클래스를 사용하는 건 적합하지 않다. 이 특징은 JPA의 지연 로딩이라는 기능과도 맞지 않다. record 클래스를 사용할 경우, 지연 로딩이나 업데이트 동작이 꼬일 수 있다.
또한, JPA는 기본 생성자(@NoArgsConstructor)을 필요로 하지만, record는 모든 필드를 한꺼번에 초기화 하는 compact constructor(@AllArgsConstructor)만 가지기 때문에 JPA가 내부적으로 프록시 객체나 리플렉션으로 인스턴스를 만들 때 문제가 생긴다.
* 프록시 객체: 원본 객체 대신 동작하는 대리 객체로, 지연 로딩 등을 위해 JPA가 내부적으로 생성함
→ record는 필드 수정이 불가능하므로 프록시로 감싸도 제대로 작동하지 않음.
* 리플렉션: 클래스나 메서드 정보를 런타임에 조회하고 조작할 수 있게 해주는 자바의 기능
→ JPA는 리플렉션으로 객체를 생성하고 필드 값을 주입하는데, record는 이를 제한함.
결론
record는 DTO, VO, 응답 모델 등 불변 데이터 객체로는 매우 유용하지만,
JPA Entity로는 부적합하다. → 대신 일반 클래스를 사용해야 함.
'DEVELOP > CONCEPT' 카테고리의 다른 글
primitive type vs wrapper class (1) | 2025.04.11 |
---|---|
final, static, static final 차이 (0) | 2025.04.11 |
SOLID 원칙 (1) | 2025.04.11 |