반응형
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' 카테고리의 다른 글
Java의 @NonNull vs @Nonnull vs @NotNull 정리 (1) | 2025.03.20 |
---|---|
Atomic Reference란? (1) | 2025.03.18 |
[Lombok][Warning] @Builder will ignore the initializing expression entirely. (0) | 2023.01.15 |
[Lombok][Warning] 상속받은 클래스에 @Data만 사용하면 Warning이 뜨는 이유 (0) | 2023.01.14 |
[Java] AssertJ 사용법 (0) | 2022.10.23 |