Home record
Post
Cancel

record

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
  • 웹 애플리케이션
  • 빅 데이터
This post is licensed under CC BY 4.0 by the author.