들어가기 앞서 Java에서 말하는 객체 직렬화는 이처럼 Java의 객체를 외부로 저장/복원하거나 네트워크 상으로 전송할 수 있도록 바이트 형태로 변환하는 기술을 의미한다.
반대로 '역직렬화'는 직렬화를 통해 변환된 바이트 형태를 다시 원상태인 객체로 변환 시키는 기술을 의미한다.
직렬화를 하게 되면 각 주소 값이 가지는 데이터를 전부 끌어 모아서 값 형식 데이터로 변환해 준다. 직렬화가 된 데이터는 언어에 따라서 텍스트 또는 바이너리 등의 형태가 되는데, 이러한 형태가 되었을 때 저장하거나 통신할 때 파싱이 가능한 유의미한 데이터가 되기 때문이다.
public class Member implements Serializable {
private String name;
private String email;
private int age;
public Member(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
@Override
public String toString() {
return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
}
}
여기서 Serializable은 현재 클래스의 객체가 직렬화가 제공되어야 함을 JVM에게 알려주는 역할만 수행한다.
java.io.ObjectOutputStream
를 사용
public static void main(String[] args){
Member member = new Member("김배민", "deliverykim@baemin.com", 25);
byte[] serializedMember;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(member);
// serializedMember -> 직렬화된 member 객체
serializedMember = baos.toByteArray();
}
}
// 바이트 배열로 생성된 직렬화 데이터를 base64로 변환
System.out.println(Base64.getEncoder().encodeToString(serializedMember));
}
serialVersionID
를 가지고 있어야 한다.+) class path는?
JVM이 프로그램을 실행할 때, class 파일을 찾는 데 기준이 되는 파일 경로
java.io.ObjectInputStream
를 사용
public static void main(String[] args){
// 직렬화 예제에서 생성된 base64 데이터
String base64Member = "...생략";
byte[] serializedMember = Base64.getDecoder().decode(base64Member);
try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedMember)) {
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
// 역직렬화된 Member 객체를 읽어온다.
Object objectMember = ois.readObject();
Member member = (Member) objectMember;
System.out.println(member);
}
}
}
앞서 말한 것처럼 역직렬화를 하게 되면 클래스의 구조가 변경된다는 문제가 발생한다.
변수 타입이 달라지면 타입 예외가 발생한다. 직렬화한 데이터의 객체의 변수 타입이 String인데, 추후 개발하면서 StringBuilder로 바꿨다면 역직렬화가 불가능하다. int를 long으로 바꾸는 것이다.
일반적인 메모리 기반의 Cache에서는 Data를 저장할 수 있는 용량의 한계가 있으므로 json 형태와 같은 경량화된 형태로 직렬화하는 것이 좋다.
steady-coding님의 글을 참조하여 작성하였습니다.