반응형
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' 카테고리의 다른 글
[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 |
[Java] 인터페이스(Interface)란? (0) | 2020.07.14 |