먼저 자바는 JVM을 이용하여 자바코드를 컴파일하여 바이트 코드로 만들어냅니다. 그리고 자바의 Object를 바이트 코드로 변경한 기술을 직렬화(Serialize)라 하고, 바이트 코드로 된 Object를 다시 자바의 Object로 읽을 수 있도록 변환된 기술을 역직렬화(Deserialize)라고 합니다. 이는 프로그램 간 데이터 전송은 객체건 뭐건 결국 바이트의 흐름으로 전송하는 데 자바 프로그램에서 바이트 데이터를 다시 읽었을 때 자바의 객체로 읽어내기 위한 기술입니다.
자바에서 직렬화 하기 위한 방법은 java.io.Serializable 인터페이스를 상속받고 상속받은 객체는 직렬화 할 수 있는 기본 조건이 됩니다.
하지만 중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 합니다. 코드는 시간이 갈수록 변하기에 시간에 따라 코드가 변함에도 불구하고 객체의 버전을 유지하기 위해선 자바 코드 모델의 버전간의 호환성을 유지하기 위한 SUID(serialVersionUID)를 정의해야 합니다.
private static final long serialVersionUID = -6120832682080437368L;
와 같이 클래스에 직접 SUID 값을 지정해버리면 JVM에서 SUID 생성 알고리즘을 사용하지 않고 이 값을 사용하게 되므로 버전에 따른 불일치 에러는 막을 수 있습니다.
만약 SUID를 지정안하면 자바 내부적으로 SUID를 생성합니다. Default SUID는 클래스의 기본 해쉬값을 사용하고, 사용 알고리즘은 Java(TM) Object Serialization Specification 정의된 것을 따른다고 합니다.
그러나 모든 serialization이 필요한 클래스에는 명시적으로 serialVersionUID를 선언해줄것을 강력하게 권유하고 있습니다.
왜냐하면 디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 하고, 컴파일러 구현체에 따라서 달라질 수 있어 역직렬화 과정에서 예상하지 못한 InvalidClassExceptions이 발생될 수 있기 때문입니다.
하지만 serialVersionUID을 붙여주어도 아래와 같이 호환성 문제가 발생되는 경우가 있을 수 있습니다.