SerialVersionUID는 클래스 버전에 대한 식별자이다.
내가 최초로 만든 Book
이라는 클래스는 이 최초의 모습을 유지하지 않고, 개발을 거듭하면서 계속해서 버전업이 될 것이다. 처음에는 title
이라는 필드만 있었지만, 나중에는 author
, content
등 여러 필드가 추가될 수 있고 또 필요에 따라 추가했던 필드를 삭제하게 될 수도 있다. 이렇게 다양하게 변모할 수 있는 클래스의 버전을 식별하기 위해 SerialVersionUID가 필요하다.
class Book implements Serializable {
private String title;
private String author;
private String content;
}
위와 같은 형태의 최초(v1)의 Book
을 직렬화한 뒤에, author
필드를 삭제하였다고 생각해보자. 이 때 직렬화했던 데이터를 다시 Book
객체로 역직렬화하려고 하면 InvalidClassException
이 발생한다. 그 이유는 다음과 같다.
자바 객체 직렬화 스펙에 따르면 직접 클래스에 SUID를 선언하지 않은 경우 JVM에 의해 해당 클래스의 64bit 해시값으로 SUID가 부여된다. 이 해시값은 클래스 이름, 인터페이스 이름, 메서드 및 필드 정보를 포함하기 때문에 메서드나 필드가 변경되면 SUID 값도 변경된다. 이 SUID를 직렬화/역직렬화 시점에 비교함으로써 직렬화/역직렬화 가능 여부를 판단하기 때문에 위 예시처럼 직렬화-역직렬화 과정 사이에 클래스 스펙이 변경되어 SUID가 달라지면 JVM은 이를 역직렬화할 수 없다고 판단하여 InvalidClassException
을 발생시킨다.
하지만 아래와 같이 SUID를 직접 선언하게 되면 클래스 스펙이 변경되더라도 늘 같은 식별자를 갖기 때문에 위와 같은 오류가 발생하지 않는다. 따라서 자바에서는 SUID 값을 직접 관리하는 것을 권장하고 있다.
class Book implements Serializable {
private static final long serialVersionUID = 1L;
private String title;
private String author;
private String content;
}
'Java' 카테고리의 다른 글
[Java] 스레드 풀(ThreadPool) 이란? ThreadPool 종류 (0) | 2024.03.12 |
---|---|
[Java] SLF4J로 예외 로깅하기 (1) | 2024.02.27 |
[Java] Unchecked Exception에 관한 논쟁 (0) | 2024.02.01 |