☕️[Java] record
란 무엇일까요?
- record는 Java 14에서 도입되고 Java 16에서 정식 출시된 새로운 클래스 유형으로, 주로 데이터를 담는 객체를 더 간단하고 간결하게 정의하기 위해 만들어졌습니다.
- 기존의 POJO(Plain Old Java Object)나 DTO(Data Transfer Object)를 더 효율적으로 표현할 수 있도록 설계되었습니다.
1️⃣ record의 주요 특징.
1️⃣ 불변 객체 생성.
- record로 생성된 클래스는 불변(Immutable)입니다.
- 즉, 생성된 객체의 필드는 변경할 수 없습니다.
2️⃣ 필드 선언의 간소화.
- record를 사용하면 필드 선언, 생성자, getter, equals, hashCode, toString 메서드를 명시적으로 작성할 필요가 없습니다.
- 컴파일러가 자동으로 생성합니다.
3️⃣ 목적.
- 데이터를 단순히 저장하고 전달하는 역할(DTO, Data Transfer Object)이나 데이터의 일관성을 유지하는 객체에 적합합니다.
4️⃣ 간결한 선언.
- 기존 클래스에 비해 선언 코드가 매우 간결합니다.
2️⃣ 코드 분석.
public record CreateUserRequest (
@Schema(description = "유저 이름")
@NotBlank
@NotNull
String name,
@Schema(description = "유저 비밀번호")
@NotBlank
@NotNull
String password
) {}
1️⃣ record 정의.
- CreateUserRequest는 record로 선언된 데이터 객체입니다.
- 내부 필드인 name과 password는 불변이며, 생성자와 getter가 자동으로 생성됩니다.
2️⃣ 필드.
- String name: 유저의 이름을 저장하는 필드.
- String password: 유저의 비밀번호를 저장하는 필드.
3️⃣ 애너테이션.
-
@Schema
- OpenAPI 문서화에서 사용되는 Swagger 애너테이션입니다.
- 필드와 클래스에 대한 설명을 추가합니다.
-
@NotBlank
- jakarta.validation.constraints의 애너테이션으로, 값이 null, 비어있음, 혹은 공백 문자열이 되지 않도록 검증합니다.
-
@NotNull
- 해당 필드가 반드시 null이 아니어야 함을 보장합니다.
3️⃣ 컴파일러가 자동으로 생성하는 내용.
1️⃣ 생성자.
- 모든 필드를 초기화하는 전체 생성자가 자동으로 생성됩니다.
public CreateUserRequest(String name, String password) { this.name = Objects.requireNotNull(name); this.password = Objects.requireNotNull(password); }
2️⃣ Getter 메서드.
- 각 필드에 대해 읽기 전용의 Getter 메서드가 제공됩니다.
```java
public String name() {
return name;
}
public String password() {
return password;
}
### 3️⃣ toString
- 객체를 문자열로 표현하는 toString 메서드가 자동으로 생성됩니다.
```java
@Override
public String toString() {
return "CreateUserRequest[name=" + name + ", password=" + password + "]";
}
4️⃣ equals와 hashCode
- 두 객체를 비교하거나 Hash 기반의 컬렉션(Map, Set 등)에서 사용할 수 있도록 equals와 hashCode 메서드가 생성됩니다.
```java
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CreateUserRequest that = (CreateUserRequest) o;
return name.equals(that.name) && password.equals(that.password);
}
@Override
public int hashCode() {
return Objects.hash(name, password);
}
```
4️⃣ 장점.
1️⃣ 코드 간소화.
- 기존 DTO에서 반복적으로 작성하던 getter, setter, toString, equals, hashCode 등을 명시적으로 작성하지 않아도 됩니다.
2️⃣ 불변성.
- 데이터 일관성을 유지할 수 있습니다.
3️⃣ 읽기 쉬움.
- 데이터를 표현하려는 목적이 분명히 드러납니다.
5️⃣ record의 제한 사항.
1️⃣ 불변 필드.
- 모든 필드는 불변이므로 값을 변경할 수 없습니다.
2️⃣ 상속 불가.
- record는 암시적으로 final로 선언되며, 상속할 수 없습니다.
3️⃣ 복잡한 로직 포함 불가.
- 데이터 객체로 설계된 만큼 복잡한 비즈니스 로직이나 추가적인 상태를 포함하기에는 적합하지 않습니다.
6️⃣ 결론.
- 결론적으로, record는 단순히 데이터를 전달하거나 저장하는 역할을 하는 클래스에 적합하며, 반복적인 코드를 제거하고 가독성을 높이는 데 매우 유용합니다.