✍️ 개발 기록

[👀 Owing] Java Record 도입기 ☕️

ming412 2024. 11. 5. 17:48

말로만 들었던 record를 드디어 이번 프로젝트에 도입하게 되었고, 관련해서 공부한 내용을 기록해두려 합니다.

 

❤️‍🔥 record 란?

Java 14부터 도입된 record 클래스는 불변 데이터를 객체 간에 전달하는 작업을 간단하게 만들어준다.

Record 클래스를 사용하면 보일러 플레이트를 줄일 수 있고, 적은 코드로도 명확한 의도를 표현할 수 있다.

 

 

❤️‍🔥 record의 특징

- 접근 제어자를 명시하지 않아도, 멤버 변수는 `private final`로 선언된다.

- 필드별 `getter`가 자동으로 생성된다.

- 모든 멤버 변수를 인자로 하는 `public 생성자`를 자동으로 생성한다.

  - `@AllArgsConstructor`와 유사하지만, record는 불변 데이터를 다루므로 생성자가 실행될 때 인스턴트 필드를 수정할 수 없다.

- 멤버 변수가 없는 기본 생성자는 제공하지 않으므로, 필요한 경우 직접 생성해야 한다.

- equals, hashcode, toString을 자동으로 생성한다.

 

❤️‍🔥 적용기

필드만 나열하면 알아서 `final`로 인식되고, `getter`, `toString` 등도 알아서 생겨서 편하게 쓸 수 있다는 점에서 DTO에 record를 적용하기로 했습니다.

 

기존 DTO 코드

public class UniverseShortInfoResponse {
    private Long id;
    private String name;
    private String description;
    private String imageUrl;

    public UniverseShortInfoResponse(String name, String description, String imageUrl) {
        this.name = name;
        this.description = description;
        this.imageUrl = imageUrl;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
}

 

일반적인 응답용 DTO 클래스입니다. 이를 record로 바꾸면 다음과 같습니다.

public record UniverseShortInfoResponse (
	Long id,
	String name,
	String description,
	String imageUrl
) { }

 

생성자를 만들고 싶으면 아래와 같이 사용하면 됩니다.

public record UniverseShortInfoResponse (
	Long id,
	String name,
	String description,
	String imageUrl
) { 
	@Builder
    public UniverseShortInfoResponse(
    	String name,
        String description,
        String imageUrl
    ) {
    	this.name = name;
        this.description = description;
        this.imageUrl = imageUrl;
    }
}

 

❤️‍🔥 개인적인 소감

1. `@AllArgsConstructor`, `@Getter` 등 lombok의 여러 어노테이션 없이 깔끔한 코드를 작성할 수 있다. 👍

 

2. 객체의 목적이 명확하게 드러난다는 점이 좋았다. 

`record`는 단순히 데이터를 담는 객체임을 명확히 나타내므로, `record`를 사용하면 코드만으로도 해당 객체가 데이터를 전달하기 위한 목적임을 쉽게 알 수 있다.

 

3. 불변성이 보장된다.

`record`는 기본적으로 불변 객체로 생성된다. 모든 필드가 `final` 이므로 한 번 초기화되면 수정이 불가능해, 의도치 않은 변경을 방지할 수 있다.