최근에 자바를 공부하다가 뭔가 이상한 코드를 보게 되었다.
package com.mysite.sbb;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "entity not found")
public class DataNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public DataNotFoundException(String message) {
super(message);
}
}
해당 코드는 사용자 정의 예외처리 메서드인데, 잘 보면 serialVersionUID라는 변수를 선언해놓고 사용하지 않는 걸 볼 수 있다.
알고 보니 이는 객체를 직렬화하는 경우 버전 관리를 위해 필요한 일종의 버전 번호였다.
직렬화란 객체를 "저장하거나 전송할 수 있는 형태"로 변환하는 것을 말한다.
이 과정에서 객체의 원본을 직접 저장하는 것이 아니기 때문에 복사가 이뤄지게 되는데, 복사된 객체의 버전이 어떤 버전인지 알아야 나중에 클래스 구조가 변경되거나, 다른 환경에서 작동을 시켜도 값이 변하지 않고 올바르게 작동한다.
만약 serialVersionUID를 명시하지 않으면, 컴파일러가 자동 생성하는데, 이럴 경우 클래스 구조 변경에 따라 값이 변할 수 있고 이는 역직렬화시 예상치 못한 오류를 발생시킬 수 있기 때문에,
serialVersionUID는 항상 명시적으로 설정해주는 것이 좋다.
참고로 역직렬화란 직렬화의 반대이다. 즉 저장/전송된 데이터를 다시 객체화시키는 것을 말한다.
객체를 "다른 곳으로 옮기거나", "나중을 위해 저장"할 필요가 있을 때 사용한다. 실제 서비스로 예를 들자면
주로 캐시나 세션과 많이 같이 쓰인다.
예외처리 클래스, DTO, 엔티티 클래스, 세션에 저장되는 객체, 캐시 객체 등이 있다.
따라서 스프링부트에서는 이러한 직렬화와 관련된 경고를 제어할 수 있도록 @Serial 어노테이션을 통해 관리할 수 있도록 해 놓았다.
해당 어노테이션은,
주로 사용된다.