직렬화(Serialization)란?

직렬화(Serialization)는 객체를 **일련의 바이트(byte stream)**로 변환하여 저장하거나 전송할 수 있도록 하는 과정입니다. 역직렬화(Deserialization)는 이 바이트 스트림을 다시 원래의 객체로 복원하는 과정입니다. 직렬화는 주로 다음과 같은 상황에서 사용됩니다:

  1. 파일 저장: 객체를 파일 시스템에 저장하기 위해.
  2. 네트워크 전송: 객체를 네트워크를 통해 다른 시스템으로 전송하기 위해.
  3. JVM 간 통신: 분산 환경에서 JVM(Java Virtual Machine) 간 객체를 주고받기 위해.

직렬화의 필요성

자바에서 객체는 메모리에 저장된 상태로 존재하며, 이를 그대로 파일이나 네트워크로 전송할 수 없습니다. 따라서 객체의 상태를 바이트 스트림으로 변환하는 직렬화 과정을 거쳐야, 이를 파일로 저장하거나 네트워크를 통해 전송할 수 있습니다.

직렬화의 사용 예

  1. 파일로 객체 저장: 객체를 파일에 저장하고 싶을 때 직렬화를 사용합니다. 이때, 객체를 직렬화된 형태로 파일에 쓰고, 나중에 이 파일을 읽어 다시 객체로 복원(역직렬화)할 수 있습니다.
  2. 네트워크를 통한 객체 전송: 소켓을 통해 네트워크로 객체를 전송하려면 직렬화가 필요합니다. 예를 들어, RMI(Remote Method Invocation)나 웹 서비스, 메시지 큐 등에서 객체를 네트워크로 전송할 때 직렬화를 사용합니다.
  3. 세션 저장: 웹 애플리케이션에서 사용자의 세션 데이터를 파일 시스템 또는 데이터베이스에 저장할 때, 세션 객체를 직렬화합니다. 이 과정은 클러스터된 환경에서 특히 중요합니다. 세션을 서버 간에 이동시키거나, 세션의 영속성을 유지하기 위해 객체를 직렬화해야 합니다.

자바에서의 직렬화

자바에서 객체를 직렬화하려면 java.io.Serializable 인터페이스를 구현해야 합니다. 이 인터페이스는 아무 메서드도 포함하지 않는 마커 인터페이스로, 이 인터페이스를 구현한 클래스의 객체만 직렬화할 수 있음을 표시합니다.

import java.io.Serializable;

public class User implements Serializable {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}

위의 User 클래스는 Serializable 인터페이스를 구현하고 있으므로, 객체를 직렬화할 수 있습니다.

자바에서 직렬화가 일어나는 순간

직렬화는 자바에서 명시적으로 요청할 때 일어납니다. 대표적인 예로 다음과 같은 경우가 있습니다:

  1. ObjectOutputStream을 사용할 때:

    User user = new User("username", "password");
    FileOutputStream fileOut = new FileOutputStream("user.ser");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(user);
    out.close();
    fileOut.close();
    
    

    이 코드는 User 객체를 user.ser 파일에 직렬화하여 저장합니다.

  2. RMI(Remote Method Invocation): 원격 객체를 호출할 때 객체가 직렬화되어 네트워크를 통해 전송됩니다.