오늘은 자바 직렬화에 대해 간단히 정리해보려고 한다.
직렬화란 컴퓨터의 메모리 상에 존재하는 데이터를 파일로써 저장하거나, 통신하는 다른 컴퓨터에게 알맞은 형식에 맞추어 전달하기 위해
바이트 스트림
형태로 만드는 것을 의미한다.
알맞은 형식이란 자바에서는 클래스
를 의미한다.
여기서 문득 궁금해졌던게, 다른 명칭이 붙었을 법도 한데 왜 직렬화라고 불리게 된걸까?
그 이유는 간단했다.
프로그램에서 사용되는 데이터들은 연속적으로 위치해 있지 않고 내부적으로
포인터에 의해 참조 되고 있는데, 이는 프로그램이 실행중인 컴퓨터에서만 인식할 수 있는 형태이다.
다른 컴퓨터와 통신하며 데이터를 알맞게 전달하기 위해서는 이렇게 흩뿌려져 있는 데이터를 한 데 모아 포인터가 존재하지 않는 일련의 바이트 형태로 만들어서 보내야 하는데 이를 보고직렬화
라고 한다.
그럼 자바에서는 직렬화를 어떻게 구현할까?
아주 간단하다.
implements Serializable
Serializable
은 마커 인터페이스
이기 때문에 따로 구현할 메서드는 존재하지 않음import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -5129628467395047900L;
String name;
int age;
double height;
String hobby;
}
다만 여기서 눈여겨 봐야 할게 있는데 바로
serialVersionUID
이다.
말 그대로 해석해보면
직렬화 버전의 고유값 이다.
즉, 직렬화/역직렬화
를 할 때 이 값으로 해당 클래스의 특정 버전에 맞는지 아닌지를 판단
하겠다는 것.
이 값을 선언하지 않으면 어떻게 될까? 직렬화가 불가능한걸까?
답은 아니오
이다.
자바 스펙에 따르면 serialVersionUID 가 선언되어있지 않을 경우 default로 값을 만들어준다고 한다.
하지만 이 값은 컴파일러의 구현에 따라 달라질 수 있기 때문에 역직렬화 시 예기치 못하게 실패할 수도 있다고 한다.
Note - It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail. 링크
자바 스펙에서도 serialVersionUID 를 선언하는 것을 강력하게 추천하고 있으니
앞으로 자바에서 직렬화를 사용하게 될 경우 필수적으로 선언해야 할 것 같다.