01 Aug 2023

[Java] Record

들어가기 전에

Java에서 레코드(Record)란 보일러플레이트 코드를 최소화하기 위해 만들어졌다.

보일러플레이트 코드(Boilerplate Code) :

최소한의 변경으로 여러곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 말한다.

예를 들어 이름, 나이, 주소 를 담고 있는 클래스가 있다고 하자. 여기서 데이터를 뽑아내려면 일반적으로 getter와 setter를 작성하여 객체 간의 불변 데이터를 전달하도록 설계한다.

class PersonInfoClass {
	String name;
	int age;
	String address;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
}

getter와 setter를 사용하기 위해서는 위처럼 메서드를 설계해야 하는데 데이터를 담기위한 클래스가 여러개라면? 반복적인 getXXX(), setXXX() 가 여러 개 만들어지며 코드가 길어질 것이다. 이를 보일러플레이트 코드라고 한다.

이를 최소화하기위해 Lombok 같은 라이브러리에서는 @라는 어노테이션을 사용해 자동으로 만들어주는 기능을 제공하기도 한다.

import lombok.*;

@Getter
@Setter
class PersonInfoClass {
	String name;
	int age;
	String address;
}

하지만 이런 코드는 라이브러리를 무조건 포함해야 한다는, Java의 한계로 작용하게 된다. 이를 해결하고자 Java14에서 preview로 Record를 선보이고, Java16에서 정식 기능으로 채택되었다.

Record의 선언법 및 특성

record PersonInfoRecord (
	String name,
	int age,
	String address // 세미콜론(;)이 아닌 쉼표(,)로 데이터 구분
) {
    static String str = "ABCD";
	
	public int getBirthYear() {
		return 2023 - age + 1;
	}
} // 중괋호 안은 static 변수나 메서드를 작성하는 곳
  • record 클래스는 final 클래스이라 상속할 수 없다.
  • 각 필드는 private final 필드로 정의되어 생성 이후에는 불변 객체가 되어 값을 변경할 수 없다.

Record의 사용법

record PersonInfoRecord (
	String name,
	int age,
	String address
) {
    static String str = "ABCDEFG";
	
	public int getBirthYear() {
		return 2023 - age + 1;
	}
}
public class RecordExample {
	public static void main(String[] args) {
		PersonInfoRecord pir = new PersonInfoRecord("전승준", 27, "대전");
        
		System.out.println("이름: " + pir.name());
		System.out.println("인사: " + pir.sayHello);
		System.out.println("생년월일: "+pir.getBirthYear());
		System.out.println(pir.toString());
	}
}

출력

이름: 전승준
인사: Hello
생년월일: 1997
PersonInfoRecord[name=전승준, age=27, address=대전]

보일러플레이트 코드를 최소화하기 위해 만들어진 데이터 클래스이기 때문에 사용법은 일반 클래스와 같다.

record를 생성할 때는 아래와 같은 내용을 포함한다.

  • 필드명을 딴 getter (getName()가 아닌 name())
  • 모든 필드를 초기화하는 public 생성자
  • 모든 필드가 일치할 때 동일한 클래스의 개체에 대해 true를 반환하는 equals 메서드
  • 모든 필드가 일치할 때 동일한 값을 반환하는 hashCode 메서드
  • 클래스 이름과 각 필드 이름 및 해당 값을 포함하는 toString 메서드

효율성

기존 class 사용 시 :


class PersonInfoClass {
	String name;
	int age;
	String address;
	
	public PersonInfoClass(String name, int age, String address) {
		super();
		this.name = name;
		this.age = age;
		this.address = address;
	}
	
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String getAddress() {
		return address;
	}

	@Override
	public String toString() {
		return "PersonInfoClass [name=" + name + ", age=" + age + ", address=" + address + "]";
	}

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

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PersonInfoClass other = (PersonInfoClass) obj;
		return Objects.equals(address, other.address) && age == other.age && Objects.equals(name, other.name);
	}
}

record 사용 시 :

record PersonInfoRecord (
	String name,
	int age,
	String address
) {}

정리

보일러플레이트 코드를 최소화하기 위해 만들어진 data class이다.

Reference

https://www.baeldung.com/java-record-keyword

https://coding-start.tistory.com/355

Thank You For Reading
SeungJun Jeon

점점 강해지고 있습니다.

comments powered by Disqus