팀장님께서
자바16에 record가 정식 스펙이라고
말해 주었다. record가 무엇인가 봤더니
재미있는 것 같아 정리를 하고 싶어서
이렇게 글을 쓰게 되었다.


record(레코드)란?

자바 14 이후부터 레코드가 preView로 추가되었고 자바 16부터는 공식 기능이 되었는데, 열거형과 마찬가지로 자바 클래스의 특별한 한 종류라고 바라볼 수 있다. 마치 클래스의 생성자와 같이 매개변수를 나열하면 되는데, 여기서는 이를 컴포넌트(component) 라고 한다.


사용법

자바를 사용하다 보면 반복적으로 비슷한 형태를 가지고 있는 코드 즉, 보일러 플레이트 코드가 많이 존재한다.  DTO를 예로 들면  getter, setter, equals, hashCode, toString 같이 반복적으로 비슷한 형태를 가지고 여러 DTO들이 존재한다.

기존 dto class 는 아래와 같은 코드로 작성하게 된다.

public class UserDto {
  
  private String name; 
  private int age;
  private String adress;
  
    public String getxxx() {  
        return xxx;  
    }  
 
    public String setxxx() {  
        return xxx;  
    }
    
    public int getxxx() {  
        return xxx;  
    }  
 
    public String setxxx() {  
        return xxx;  
    }
    
    public String getxxx() {  
        return xxx;  
    }  
 
    public String setxxx() {  
        return xxx;  
    }

    @Override  
    public int hashCode() {  
        return Objects.hash(xxx,xxx,xxx);  
    }
}

 

보일러 플레이트 코드를 레코드를 사용하면 아래 코드 한 줄로 줄일 수 있다. 

public record UserDto(String name, int age, String adress) {}

 


특징

 

  •   record는 필드를 선언하면 private final 필드로 선언된다. 즉 한 번 값이 정해지면
      setter를 통해 값을 변경할 수 없다. 
  • 레코드 내부에 멤버 변수를 선언할 수 없다 하지만 static 변수는 생성이 가능하다.
  • 접근자와 생성자, toString, equals, hashCode를 선언하지 않아도 이에 대한 구현을 자동으로 제공한다.
  • getter를 사용할 때 컴포넌트의 이름만 사용하면 됨. 즉, name(), age() 처럼 필드의 이름으로 사용한다.
  • 다른 클래스를 상속 받을 수 없지만 인터페이스로는 구현이 가능하다.
  • 제네릭 레코드를 만들 수 있다.
  • new 키워드를 사용하여 레코드를 인스턴스화할 수 있다.
  • 레코드나 레코드의 각 컴포넌트에 애노테이션을 달 수 있다.

 


컴팩트 생성자

만약 별도의 초기화 로직이 필요하다면 레코드 안에 표준 생성자를 만들 수도 있고,  내부에는 final로 선언된 인스턴스 필드가 있어서 생성자 안에서 모두 초기화해야 해여 한다.

public record User(String name, int age, String adress) {    
   
    public User(String name, int age, String adress) {
        this(name, age, adress);
    }
}

 

표준 생성자 말고도 컴팩트 생성자를 사용할 수도 있는데 생성자 매개변수를 받는 부분이 사라진 형태이다.

public record Book(String name, int age, String adress) {

    public Book {
        Objects.requireNonNull(name);
        Objects.requireNonNull(age);
        Objects.requireNonNull(adress);
    }
}

 


참고한 자료

https://blog.hexabrain.net/399

https://openjdk.org/jeps/359

https://velog.io/@power0080/java%EC%9E%90%EB%B0%94-record%EB%A5%BC-entity%EB%A1%9C

 

 

복사했습니다!