JAVA14 Record Keyword

Daniel·2023년 8월 9일
0

Back-End

목록 보기
25/48

Record 란?

  • Immutable(불변) 데이터 객체를 쉽게 생성할 수 있도록 하는 새로운 유형의 클래스입니다.
  • JDK14에서 preview로 등장하여 JDK16에서 정식 스펙으로 포함되었습니다.
  • record(레코드) 란 "데이터 클래스이며" 순수하게 데이터를 보유하기 위한 특수한 종류의 클래스 입니다. (코틀린의 데이터 클래스와 비슷하다고 합니다.)
  • 간결하고 가벼워서 Entity 혹은 DTO 클래스를 생성할 때 사용하기도 합니다.

기존) 불변 객체

public class Person{
	private final String name;
	private final int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(name, address);
		}
		
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		} else if (!(obj instanceof Person)) {
			return false;
		} else {
			Person other = (Person) obj;
			return Objects.equals(name, other.name) && Objects.equals(address, other.address);
		}
	} 
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", address=" + address + "]";
	}
}

문제점

  • Boilerplate Code
    각 데이터 클래스에 대해 동일한 프로세스를 반복해야한다.
    (equals, hashCode 및 toString 메서드를 생성하고, 각 필드를 받아들이는 생성자를 생성)
    IDE 또는 어노테이션은 이러한 많은 클래스를 자동으로 생성할 수 있지만, 새 필드를 추가할 때 클래스를 자동으로 업데이트하지는 못한다.

  • 클래스의 목적이 모호해진다.
    위 클래스의 목적은 무엇일까? 이름(String name)과 나이(int age)를 가진 사람을 표현한다.
    하지만 추가된 코드로 인해 데이터 클래스라는 사실이 모호해진다.

Record) 불변 객체

public record Person(String name, int age) {
	;;
}
  • 레코드 클래스를 사용하면 훨씬 간결한 방식으로 동일한 불변 데이터 객체 정의할 수 있음
    - 이름(Person), 헤더(String name, int age), 바디({})

  • 컴파일러는 헤더를 통해 내부 필드를 추론
    - 생성자를 작성하지 않아도 되고 toString, equals, hashCode 메소드에 대한 구현을 자동으로 제공(Java 컴파일러에 의해 생성)

Record) Compact Constructor(컴팩트 생성자)

기본 생성자 이외의 추가적인 사용자정의로직이 필요하다면 Compact Constructor(컴팩트 생성자)를 활용해보자.

장점

  • 자동 초기화: 일반 클래스 생성자와 달리 컴팩트 생성자는 명시적인 인스턴스 필드 초기화가 필요하지 않습니다. 초기화 문은 자동으로 포함됩니다.
  • 불변 구성 요소: 컴팩트 생성자는 구성 요소에 입력된 값을 불변으로 만드는 것과 같은 작업에 적합합니다.
  • 유효성 검사: 특정 조건이 충족되는지 확인하여 불변량을 검증하는 데에도 유용합니다.

제한사항

  • No Field Access: 컴팩트 생성자는 인스턴스 필드에 대한 액세스를 허용하지 않습니다. 이렇게 하면 오류가 발생합니다. 예를 들어 생성자 내에서 this.value를 사용하면 필드가 아직 초기화되지 않았기 때문에 오류가 발생합니다.
  • Final Variable Constraintprivate final 인스턴스 필드의 사용은 Compact Constructor에서 사용되는 변수로 확장되지 않습니다. 이러한 변수는 여러 번 할당될 수 있으며 마지막으로 할당된 값으로 초기화됩니다.
public record Person(String name, int age) {
	public Person{
		Object.requireNonNull(name);
		Object.requireNonNull(age);
	}
}

위 처럼 생성한 생성자는 일반 생성자를 사용하듯 똑같이 사용할 수 있습니다.

Person daniel = new Person("Daniel", "31");

Note

과장님이 만드시고 내가 유지보수를 맡게된 플젝에서 Record를 사용해 짜놓은 로직들이 보였다.
레코드... 이름만 알고있었지 자세하게 알고있지는 않아서 공부해보고 정리한 내용을 바탕으로 블로그에 기록해봤는데
공부한 내용 기반으로 Record를 사용해 데이터 모델링을 해봐야겠다.

Reference

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

profile
응애 나 애기 개발자

0개의 댓글