불변 데이터를 간단명료하게 정의할 수 있는 JAVA의 Record 기술
Record란?
- 자바 14버전에 처음 등장하여 16버전에서 정식 스펙이 되었다.
- 데이터 전송 객체(DTO)나 값 객체(VO) 같은 불변 데이터를 간단하고 명확하게 정의할 수 있게 해준다.
Record의 등장 배경
- 기존 클래스 사용에 있어서 반복적이고 귀찮은 코드인
보일러 플레이트 코드
를 줄이기 위해 도입되었다.
[보일러 플레이트 코드]
- 최소한의 변경으로 여러 곳에서 재사용되며 반복적으로 비슷한 형태를 가지고 있는 코드를 말한다.
- 자바에서는
getter
,setter
,equals
,hashCode
,toString
등이 해당된다.
[기존 클래스 코드 예시]
- 아래 코드를 보면 필드가 3개밖에 없는 간단한 클래스임에도 보일러 플레이트 코드들로 인해 가독성이 떨어지는 것을 확인할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class Employee {
private String name;
private int age;
private String department;
public Employee(String name, int age, String department) {
this.name = name;
this.age = age;
this.department = department;
}
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 getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return age == employee.age &&
Objects.equals(name, employee.name) &&
Objects.equals(department, employee.department);
}
@Override
public int hashCode() {
return Objects.hash(name, age, department);
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", department='" + department + '\'' +
'}';
}
}
Record 적용 예시
- 먼저 위의 코드를 record를 사용했을 때에는 어떻게 바뀌는지 살펴보고 특징을 알아보겠다.
- class 대신 record를 사용하였고, 필드들은 인자값의 형태로 담기게 된다.
레코드명(헤더), {바디}
의 구조로, 헤더에 나열되는 필드를 컴포넌트 라고 부른다.- 단 1줄의 코드로
getter
,toString
등의 다양한 기능들을 자동으로 사용할 수 있게 된다.
1
public record Employee(String name, int age, String department) {}
특징
[1. 불변성]
- record는 불변 객체로
abstract
로 선언할 수 없고, 암시적으로final
로 선언된다. - 즉, 한 번 값이 정해지면 setter로 값을 변경할 수 없다.
- record 내 각 필드들은
private final
로 정의된다. - 불변성이라는 특징 덕분에
Thread-Safe
하고, 안정성, 효율성, 간결성 등을 보장받게 되었다.
[2. 상속 불가]
- 불변성이라는 특징으로 인해, 상속이 불가능하다.
하지만 인터페이스로는 구현이 가능하다.
- 사실 상속이 불가능하다는 특징은 기술 선택에 있어 꽤 치명적이라고 할 수 있다.
- DTO를 사용할 때에는 보통 여러 개를 사용하고, 공통 필드가 생기기에 상속으로 부모 DTO 클래스를 만드는 경우가 종종 있다.
- 이러한 상황에서 record는 공통 필드를 묶기가 어렵다.
인터페이스로 묶을 수는 있지만, 상대적으로 불편한 형태가 된다.
[3. 보일러 플레이트 코드 자동 생성]
- 위의 예시에서 볼 수 있듯 record를 사용하기만 하면 필드 정의, 생성자,
eqluals
,hashCode
,toString
메서드 등을 자동으로 생성해준다.
(번외) Lombok
- 자바의 프레임워크인 스프링을 사용해본 사람들이라면
Lombok
라이브러리로 충분히 해결될 수 있는 문제 아니냐는 의문이 들 수 있다. - 실제로 lombok의
@Data
어노테이션을 사용하면 별도로 구현할 필요없이 간단하게 사용할 수 있다.이 어노테이션은 대부분의 보일러 플레이트 코드들을 자동으로 생성해주는 기능을 수행한다.
1
2
3
4
5
6
7
8
import lombok.Data;
@Data
public class Employee {
private String name;
private int age;
private String department;
}
Record를 꼭 사용해야 할까?
- 위의 lombok을 보면 알 수 있듯이 사실 보일러 플레이트 코드를 줄이는 기술은 이미 존재한다.
- 게다가 record는 상속을 하지 못한다는 특징 때문에 DTO의 개수가 많아져도 공통 필드를 묶지 못한다.
- 그럼에도 record는 온전한 자바의 기술이기 때문에 자바 기술이 발전함에 따라 사용성이 증가할거라는 기대가 있으므로 자바 유저라면 알아두자.
누군가가 물어본다면
Record
는 자바16의 기술로, 변경이 적고 반복되는 코드를 줄여주는 기술입니다.
하지만 불변성이라는 특징으로 상속이 불가능하여, 사용하기 애매하다는 점이 있습니다.
This post is licensed under CC BY 4.0 by the author.