본문 바로가기
Java

레코드 (record)

by 밝지 2024. 9. 13.
728x90
반응형

record의 구조 및 특징

// 레코드명(헤더) { 바디 }
public record Subin(String name, int age, String gender) { }
  • 헤더에 나열된 필드 (String name, String age, String gender) = 컴포넌트
  • 레코드의 각 필드(=헤더에 나열한 컴포넌트)는 private final
  • 즉, 위의 예시는 이름은 Subin, name, age, gender를 private final 필드로 가진 레코드
  • 레코드에서는 헤더에서 정의한 멤버만을 관리한다. => 내부에 멤버 변수 선언 불가. static 변수는 생성 가능.
  • 레코드는 불변 객체로 abstract로 선언 불가. 묵시적으로 final로 선언. 한 번 정해진 값은 setter를 통해 변경할 수 없고, 상속도 할 수 없다. 
  • 컴파일러는 헤더를 통해 내부 필드를 추론하여 접근자, 생성자, toString, equals, hashCode를 명시적으로 선언하지 않아도 이를 자동으로 구현한다. 
  • 레코드는 개발자가 명시적으로 인스턴스 필드를 초기화하지 않아도 모든 필드를 초기화 할 수 있는 생성자 하나만을 자동으로 생성한다. = 컴팩트 생성자
  • 보통 컴팩트 생성자는 입력 받은 데이터를 검증할 때 사용한다. (null 값 여부, 음수 여부 등을 확인하여 에러를 반환할 수 있다.)
    • 예) 매개 변수 값이 null인지 체크하고, null인 경우 에러를 반환
// 레코드명(헤더) { 바디 }
public record Subin(String name, int age, String gender) { 
	
    // 컴팩트 생성자
    public Subin {
    	Objects.requireNonNull(name);
        Objects.requireNonNull(age);
        Objects.requireNonNull(gender);
    }
}
  • 별도의 생성자가 필요한 경우 추가 가능하다.
// 레코드명(헤더) { 바디 }
public record Subin(String name, int age, String gender) { 
	
    // 컴팩트 생성자
    public Subin {
    	Objects.requireNonNull(name);
        Objects.requireNonNull(age);
        Objects.requireNonNull(gender);
    }
    
    // 추가 
    public Subin(int age) {
    	this.name = "Subin";
        this.age = age;
        this.gender = "Female";
    }
}

 

 

유의할 점

보일러 플레이트를 방지한다는 면에서 매력적이라 JPA의 entity로 쓰고 싶겠지만 record는 entity가 되기에는 부적절하다.

  • 프록시 생성을 위해서 entity는 불변이어서는 안된다. 
  • 쿼리 결과 매핑 시 매개변수가 없는 생성자가 필요하다. 하지만 레코드는 매개변수가 없는 생성자를 제공하지 않는다. setter를 사용할 수 없기 때문에 모든 필드의 값을 입력해야 생성할 수 있다. 
  • 레코드의 getter는 필드명을 그대로 사용하기 때문에(예: age(), name()) 쿼리 결과 수행 후 접근이 어렵다. 
  • record는 DTO로 사용하는 것이 적절하다.
728x90
반응형

'Java' 카테고리의 다른 글

프롤로그  (1) 2024.05.28