Record
Java 14부터 도입된 Record는 불변 데이터를 쉽게 생성할 수 있도록 도와주는 새로운 유형의 클래스이다.
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
public class Student {
private final String name;
private final int number;
public Student(String name, int number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public int getNumber() {
return number;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return number == student.number && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, number);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", number=" + number +
'}';
}
}
위와 같은 코드를 아래와 같이 간단하게 사용할 수 있도록 해준다.
1
2
public record StudentRecord(String name, int number) {
}
특징
- 멤버 변수는 private final로 선언된다.
- 필드별 getter가 자동으로 생성된다.
- 모든 멤버변수를 인자로 하는 public 생성자를 자동으로 생성한다.
- @AllArgsConstructor와 유사하지만, record는 불변 데이터를 다루기 때문에 생성자가 실행될 때 필드를 수정할 수 없다.
- equals, hashcode, toString을 자동으로 생성한다.
- 기본 생성자는 제공하지 않으므로 필요한 경우 직접 생성해야 한다.
기본적으로 Record 클래스가 제공해주는 메서드들(생성자 등)은 재정의가 가능하다.
컴팩트 생성자 기능을 제공한다.
1
2
3
4
5
6
public record Student(String name, int number) {
public Student {
validate(name, number);
}
}
생성자에 this.name = name 같은 필드값 초기화를 자동으로 필드값을 가져와 처리해주고, 개발자가 생성자에 필요한 로직을 넣고 싶다면 위와 같이 간단하게 정의하면 된다.
정적 필드를 제외한 모든 필드값은 선언 시 정의되어야 한다.
1
2
3
4
public record Student(String name, int number) {
private static final int CLASS_NUM = 6;
private final Grade grade; // 불가
}
static이 아닌 비정적 필드값들은 레코드의 선언 시 정의되어야 한다.
즉 Student(String name, int number, Grade grade) 여야 한다.
반면 static 키워드를 사용하는 정적 필드값은 추가 가능하다.
기존 클래스와 동일하게 메서드를 추가해 사용할 수 있다.
1
2
3
4
5
public record Student(String name, int number) {
public void anything() {
System.out.println("ok");
}
}
메서드를 구현하고 싶다면 기존 클래스와 동일하게 메서드를 정의할 수 있다.
확장이나 상속이 불가능한 final 클래스이다.
레코드는 확장이나, 상속이 불가능한 final 클래스이다. 앞에 final이 생략되어 있다고 볼 수 있다.
모든 필드값은 private final 이어야 한다.
모든 필드값은 final 키워드로 정의하기 때문에 생성자를 통해서만 정의된다. 한 번 정의되면 값이 변하지 않는다. setter가 없는 것도 이 때문이다.
장점
- 코드의 작성 및 유지보수를 쉽게 할 수 있다.
- 함수형 프로그래밍을 쉽게 할 수 있다.
함수형 프로그래밍을 쉽게 할 수 있다.
자바 레코드는 객체를 함수형 프로그래밍에서 사용할 수 있는 인터페이스를 제공하기 때문이다. 이로 인해 개발자는 함수형 프로그래밍을 사용하여 코드를 더 간결하고 효율적으로 작성할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
List<Student> students = List.of(
new Student("Alice", 1),
new Student("Lee", 2),
new Student("kim",3)
);
List<Student> filterStudent = students.stream()
.filter(student -> student.number >= 2)
.toList();
filterStudent.stream().forEach(System.out::println);
//결과
Student[name=Lee, number=2]
Student[name=kim, number=3]
함수형 프로그래밍의 중요한 특징 중 하나인 불변성을 보여준다. record
클래스는 불변이므로, 한 번 생성된 객체는 수정될 수 없다. 따라서 스트림 연산을 통해 새로운 컬렉션을 생성하거나 변환할 때 기존 객체를 변경하지 않는다.
단점
- 상속을 지원하지 않는다.
- 인터페이스를 구현하지 않는다.
- 멀티스레드 환경에서 안전하지 않다.
활용 사례
- 데이터베이스 ORM
- 웹 애플리케이션
- 빅 데이터