프로젝트에 대해서 면접관은 정말 다양한 질문을 한다. Spring Project를 했다 하면 질문하는 것 중의 하나는 다음과 같다.
Java는 몇 버전을 사용하셨고 이유가 뭔가요 ?
- 나는 보통 Spring과의 호환성을 위해 버전 업을 했다고 얘기한다.
정확하게 원하는 답변이 뭔지는 잘 모르겠지만 틀린 말은 아니라고 생각한다. 실제로 많이 사용하는 Spring Boot 3.0부터는 Java 17이 필수다.
이러한 이류로 Java 17을 사용한다면 17의 특징을 살려 프로그래밍을 해보는 것도 좋다 생각한다.
Java 17에는 다양한 변화가 적용되었다. 대표적인 키워드로는 다음과 같다.
- Record class
- Sealed class
- Stream.toList() 사용 가능
- ZGC의 등장
다양한 변경점이 있지만 오늘 내가 다루고 실제로 적용한 주제는 Record Class이다.
Java 14에 등장한 불변(immutable)객체를 쉽게 생성할 수 있도록 하는 유형의 클래스
자세한 설명 참고 : https://www.baeldung.com/java-record-keyword
객체 생성 이후 내부 상태가 변하지 않는 객체 → Read Only 메서드만을 제공 (대표적으로 String 클래스 객체들)
- 불변 객체의 가장 큰 장점은 동기화를 고려하지 않아도 된다는 것이다.
Java 17 이전에도 불변 객체라는 개념은 존재했고 당연히 정의 가능했다. 그렇다면 Java 진영은 왜 17에 Record라는 별도의 클래스까지 도입했을까?
Baeldung에는 다음과 같이 기술되어 있다.
public class Person {
private final String name;
private final String address;
public Person(String name, String address) {
this.name = name;
this.address = address;
}
@Override
public int hashCode() {
return Objects.hash(name, address);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (!(obj instanceof Person)) {
return false;
} else {
Person other = (Person) obj;
return Objects.equals(name, other.name)
&& Objects.equals(address, other.address);
}
}
// standard getters
}
public record Person (String name, String address) {}
컴파일러는 레코드의 목적(단순히 데이터를 담는 불변 객체)을 이해하고, 이에 필요한 메서드와 필드를 자동으로 생성
위에서는 Java 17에서 사용되는 Record Class에 대해 알아보았다. 그렇다면 어디에 쓸까? 다양한 활용법이 있지만 내가 적용한 것은 DTO이다.
계층간 데이터 교환을 위해 사용되는 객체로서 불변성을 보장한다.
- 자세한 설명은 주제를 벗어나는 거 같으니 생략하고 ‘불변성’에 집중해보겠다.
- DTO는 Record Class가 적용되기 굉장히 적합하다.
@Getter
@NoArgsConstructor
public class AssignCardWorkRequest {
private UUID workerId;
private String workerEmail;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private LocalDateTime startDate;
@JsonFormat(shape = JsonFormat.Shape.STRING)
private LocalDateTime endDate;
private String description;
}
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import java.util.UUID;
public record AssignCardWorkRequest(
UUID workerId,
String workerEmail,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
LocalDateTime startDate,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
LocalDateTime endDate,
String description
) {}