개발/Java

Java 14 Record Keyword

nova_dev 2024. 11. 22. 22:00
반응형

1. record 키워드란?

  • 객체 간에 변경 불가능한 데이터를 전달할 경우 사용
    • 데이터베이스의 결과, 쿼리 결과, 서비스 정보 등 간단한 데이터를 보관하기 위해 클래스를 작성한다. 이 경우 많은 경우 변경 불가능한 데이터이다.
  • record keyword에서 포함하는 것
    • private 필드
    • getter
    • public 생성자
    • equals 메서드
    • hashCode 메서드
    • toString 메서드

2. 예시

import java.util.Objects;

public class Shop {
    private final String name;
    private final String address;

    public Shop(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Shop shop = (Shop) o;
        return Objects.equals(name, shop.name) && Objects.equals(address, shop.address);
    }

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

    @Override
    public String toString() {
        return "Shop{" +
                "name='" + name + '\\'' +
                ", address='" + address + '\\'' +
                '}';
    }
}

위 코드에는 많은 보일러플레이트 코드가 있고 새 필드를 추가할 때마다 메서드를 추가로 수정해주어야 합니다.

Java 14부터는 위와 같은 반복적인 데이터 클래스를 레코드 클래스로 대체할 수 있습니다.

public record ShopRecord(String name, String address) {}
    @Test
    void testEquals() {
        Shop shop1 = new Shop("마트", "서울시 강남구");
        Shop shop2 = new Shop("마트", "서울시 강남구");
        assertEquals(shop1, shop2);
        System.out.println(shop1);
        System.out.println(shop2);
    }

    @Test
    void testRecordEquals() {
        ShopRecord shop1 = new ShopRecord("마트", "서울시 강남구");
        ShopRecord shop2 = new ShopRecord("마트", "서울시 강남구");
        assertEquals(shop1, shop2);
        System.out.println(shop1);
        System.out.println(shop2);
    }

위 테스트코드의 결과는 같습니다. 다만 shop2의 toString의 괄호는 대괄호([])입니다.

3. record - 생성자, static 변수, 메서드

추가로 record 클래스에는 일반 클래스와 동일하게 static 변수를 추가할 수도 있으며 static 메서드를 추가할 수도 있습니다.

또한 생성자도 추가로 작성이 가능합니다.

package com.study.devstudy.java.record;

public record ShopRecord(String name, String address) {
    public static String UNKNOWN_ADDRESS = "Unknown";

    public ShopRecord(String name) {
        this(name, UNKNOWN_ADDRESS);
    }

    public ShopRecord {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("상점 이름은 필수입니다.");
        }
        if (address == null || address.isBlank()) {
            throw new IllegalArgumentException("상점 주소는 필수입니다.");
        }
    }

    public static ShopRecord unnamed(String address) {
        return new ShopRecord("Unnamed", address);
    }
}

    @Test
    void testRecordCreator() {
        ShopRecord shop1 = new ShopRecord("마트");
        ShopRecord shop2 = ShopRecord.unnamed("서울시 강남구");
        Assertions.assertEquals("마트", shop1.name());
        Assertions.assertEquals("Unknown", shop1.address());
        Assertions.assertEquals("Unnamed", shop2.name());
        Assertions.assertEquals("서울시 강남구", shop2.address());
        Assertions.assertThrows(IllegalArgumentException.class, () -> new ShopRecord(null, null));
    }

참고 자료

Java Record Keyword | Baeldung

반응형