직렬화와 역직렬화

parkrootseok·2025년 8월 13일
0

자바

목록 보기
19/19
post-thumbnail

직렬화

직렬화란?

직렬화는 자바 객체를 바이트 스트림으로 변환하는 과정입니다. 이 과정 덕분에 객체를 파일로 저장하거나, 네트워크로 전송할 수 있습니다.

동작 방식

자바에서는 ObjectOutputStream 클래스를 사용하여 아래와 같이 직렬화를 수행합니다.

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerializationExample {

    static class FileDto implements Serializable {	    // 반드시, Serializable 구현 필요
        private static final long serialVersionUID = 1L;	// 클래스 버전 관리 (역직렬화 시 호환성 보장)
        private transient String password;	// transient 키워드가 선언된 필드는 직렬화 제외 (static도 해당)
        private String name;
        private int size;

        public FileDto(String name, int size) {
            this.name = name;
            this.size = size;
        }
    }

    public static void main(String[] args) {
        try {
        	// 직렬화 대상
            FileDto dto = new FileDto("example.txt", 1024);
            
            // 직렬화 수행
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.dat"));
            
            // writeObject()는 자바 객체를 바이트 스트림으로 변환 후
            // 해당 스트림을 연결된 출력 대상에 기록
            // - 클래스 메타데이터, serialVersionUID 저장
            // - transient, static은 제외
            // - 참조 타입이 있을 경우, 재귀적으로 직렬화
            oos.writeObject(dto);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

static 변수는 왜 (역)직렬화하지 않나요?

static 필드는 Method Area에서 관리되는 상태로, 인스턴스의 상태가 아닌 클래스 전체가 공유하는 상태입니다. 즉, static 필드를 굳이 각 객체에 저장할 필요가 없다는 것을 의미합니다.

역직렬화란?

역직렬화는 바이트 스트림을 다시 자바 객체로 변환하는 과정입니다. 이 과정을 통해 파일이나 네트워크에서 받은 데이터를 원래의 객체 상태로 복원할 수 있습니다.

동작 방식

자바에서는 ObjectInputStream 클래스를 사용하여 아래와 같이 역직렬화를 수행합니다.

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class DeserializationExample {
    static class FileDto implements Serializable {	// 반드시, Serializable 구현 필요
        private static final long serialVersionUID = 1L;	// 클래스 버전 관리 (역직렬화 시 호환성 보장)
        private transient String password;	// transient 키워드가 선언된 필드는 역직렬화 제외 (static도 해당)
        private String name;
        private int size;

        public FileDto(String name, int size) {
            this.name = name;
            this.size = size;
        }

        @Override
        public String toString() {
            return "FileDto{name='" + name + "', size=" + size + "}";
        }
    }

    public static void main(String[] args) {
        try {
            // 역직렬화 수행
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
            
            // readObject()는 obj.dat에 저장된 바이트 스트림을 읽어
            // 클래스 메타데이터와 serialVersionUID를 확인한 후 객체 복원
            // - 복원 과정에서 기본 생성자 호출 X
            // - serialVersionUID가 일치하지 않으면 InvalidClassException 발생
            FileDto dto = (FileDto) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
profile
동료들의 시간과 노력을 더욱 빛내줄 수 있는 개발자가 되고자 노력합니다.

0개의 댓글