-
[JAVA] Java Record 란?DEV/JAVA 2024. 6. 5. 01:41
Record란?
변경이 불가한 데이터 객체를 쉽게 만들 수 있도록 해준다. 클래스보다 간결하고 효율적으로 데이터 객체를 생성할 수 있도록 설계되었다. Java14에서 preview로 나왔고 Java16에서 정식기능으로 포함되었다.
목표
- 데이터를 간결하게 표현하기 위한 방법 제공
- 개발자가 불변 데이터를 모델링하는데 집중하도록 함
- 데이터 지향 메서드를 자동으로 구현
특징
- 간결성 : 필드를 정의하면 해당 필드를 기반으로 자동으로 메서드가 생성되어 코드의 양을 줄일 수 있고, 불필요한 보일러플레이트 코드를 줄여 가독성을 높여준다.
- 메서드 자동 생성 : 필드를 기반으로 equals(), hashCode(), toString() 메서드를 자동으로 생성한다.
- 생성자 자동 생성 : 필드를 기반으로 자동으로 생성자를 생성한다. (기본 생성자는 제공하지 않으므로 필요한 경우 직접 생성해야한다.)
- 불변성 : 필드가 한번 설정되면 값을 변경할 수 없다. 이는 데이터의 안정성을 높이는데 도움이 된다.
- fianl 선언 생략 : 불변 객체로서 abstract로 선언할 수 없으며 암시적으로 private final로 선언된다.
- 패턴 매칭 통합 : Java의 Pattern Matching과 함께 사용될 수 있어, 데이터 추출 및 패턴 일치 검사에 효과적으로 사용될 수 있다.
- 데이터 전달 : record의 주된 목적은 객체 간에 불변 데이터를 전달하는것으로서 DTO를 표현하는데 적합하다.
보일러 플레이트 코드
최소한의 변경(인자, 혹은 결과 타입)으로 여러 곳에서 재사용 되면서 반복적으로 비슷한 형태를 가지고 있는 코드
→ getter, setter, equals, hashCode, toString 메서드제약사항
- abstract일수 없어 다른 클래스를 상속받을 수 없다.
- 한 번 값이 정해지면 setter를 통해 값을 변경할 수 없다.
- 레코드 내부에 private final 이외의 멤버 변수(인스턴스 필드)를 선언할 수 없다. 그러나 static 변수는 생성이 가능하다. 이는 헤더에서 정의한 멤버만을 record에서 관리하기 위함이다.
위의 주요 특징을 제외하고는 자바의 클래스 개발과 동일하게 사용할 수 있다.
- new 키워드를 통해 객체화 가능
- static 메소드, static 필드 선언 가능
- 중첩 클래스 사용 가능 및 제너릭 타입으로 지정 가능
- 인터페이스 구현 가능
Class (AS-IS)
import java.util.Objects; public class User { private Long id; private String name; private int age; public User(Long id, String name, int age) { this.id = id; this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } 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; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return getAge() == user.getAge() && Objects.equals(getId(), user.getId()) && Objects.equals(getName(), user.getName()); } @Override public int hashCode() { return Objects.hash(getId(), getName(), getAge()); } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\\'' + ", age=" + age + '}'; } }
User user = new User(1L, "김개발", 25); System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getAge());
Record(TO-BE)
class 대신 record를 사용한다.
public record User(Long id, String name, int age) { }
→ private final 필드 id, name, age를 가진 User record로 간결하게 표현이 가능하다.
User user = new User(1L, "김개발", 25); //getter 사용법 : 필드명으로 사용 System.out.println(user.id()); System.out.println(user.name()); System.out.println(user.age()); //toString(), equals() System.out.println(user.toString()); System.out.println(user.equals(new User(2L,"김개발", 26)));
레코드명(헤더), {바디}의 구조를 가지는데 헤더에 나열되는 필드를 컴포넌트라고 부른다.
컴파일러는 헤더를 통해 내부 필드를 추론하고, 코드에 명시적으로 접근자와 생성자, toString(), equals(), hashCode()를 선언하지 않아도 이에 대한 구현을 자동으로 제공한다.
참고포스팅
https://velog.io/@pp8817/record
https://blog.naver.com/seek316/223341255150 https://colevelup.tistory.com/28
'DEV > JAVA' 카테고리의 다른 글