JAVA
자바 직렬화(Serialization)
icedstone
2025. 3. 9. 15:07
반응형
직렬화: 객체를 스트림으로 변환하는 것
역직렬화: 스트림을 객체로 변환하는 것
serialVersionUID
JVM은 직렬화와 역직렬화를 하는 시점의 클래스에 대한 버전 번호를 부여합니다.
만약 그 시점에 클래스의 정의가 바뀌어 있다면 새로운 버전 번호를 할당합니다.
그래서 직렬화 할 때의 버전 번호와 역직렬화를 할 때의 버전 번호가 다르면 역직렬화가 불가능하게 될 수도 있습니다. 이런 문제를 해결하려면 개발자가 직접 버전 번호를 정해주면 됩니다.
class 정보가 변경되어도 같은 class로 인식하기를 원한다면 serialVersionUID를 선언해주면 된다.
만약에 아래 상황을 살펴보자
public class TestClass implements Serializable {
String test1;
}
//생성자나 기타 소스는 생략할게요
public class Main {
public static void main(String[] args) {
TestClass testClass = new TestClass("1");
byte[] data = covertToByte(testClass);
writeFile(data)
}
}
//byte[] convertToByte(Object object)
//void writeFile(byte[] data)
//기타 method는 생략할게요
TestClass를 수정하게 되어서 다음과 같이 수정했다.
public class TestClass implements Serializable {
String test1;
String test2;
}
이 상황에서
public class Main {
public static void main(String[] args) {
byte[] data = readFile();
TestClass testClass = (TestClass) convertToObject(data);
}
}
//byte[] readFile()
//Object convertToObject(byte[] data)
를 하게 된다면 다음과 같은 오류가 발생한다.
java.io.InvalidClassException: Main$TestClass; local class incompatible: stream classdesc serialVersionUID = 4560265494419914312, local class serialVersionUID = -1723379655482829338
만약 serialVersionUID가 있었다면 어떻게 되었을까?
public class TestClass implements Serializable {
private static final long serialVersionUID = 1L;
String test1;
String test2;
}
public class Main {
public static void main(String[] args) {
byte[] data = readFile();
TestClass testClass = (TestClass) convertToObject(data);
System.out.println(testClass);
}
}
결과는 TestClass{test1='1', test2='null'} 로 역직렬화가 된 것을 확인할 수 있다.
반응형
참고
transient: 직렬화에서 제외시켜주는 예약어
static: 자동적으로 직렬화 대상에서 제외된다.
반응형