[Java] 24. 직렬화(Serializable)


우선 직렬화에 앞서 스트림에 자바에서 말하는 스트림에 대해서 알고 가자. 자바에서 입출력을 수행하려면, 즉 어느 한쪽에서 다른 쪽으로 데이터를 전달하려면, 두 대상을 연결하고 데이터를 전송할 수 있는 무언가가 필요한데 이것을 스트림이라 한다. 즉, 스트림이란 데이터를 운반하는 통로이다.

스트림은 단방향 통신만 가능하기 때문에 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없다. 동시에 수행하려면 입력스트림과 출력스트림 모두 필요하다.

프로그램 간에 데이터 통신은 결국은 입출력 스트림으로 주고 받는데, 바이너리 형태로 데이터를 입출력하는 스트림을 이진스트림, 문자형태로 입출력하는 스트림을 텍스트스트림이라고 합니다.


직렬화(Serialization)란?

자바에서 직렬화(Serialization)는 객체를 데이터 스트림으로 변환하여 저장하거나 네트워크를 통해 전송할 수 있는 기술입니다. 이를 통해 객체를 파일에 저장하거나 네트워크를 통해 다른 시스템에 전송하여 다시 객체로 복원할 수 있다.


자바에서 직렬화란?

직렬화는 주로 Serializable 인터페이스를 구현한 클래스에서 사용됩니다. 이 인터페이스를 구현하면 자바 시스템은 해당 클래스의 객체를 바이트 스트림으로 변환할 수 있게 된다.

그래서 인터페이스 Serializable 가 implements가 되어있는 클래스는 직렬화가 가능한 객체라는 것을 알 수 있으며, Serializable가 존재하지 않는 클래스는 직렬화하지 않겠다는 설계로 출력스트림을 하지 않겠다고 볼 수 있다.

java.io.Serializable

public class User implements Serializable {
    public long id;
    public String userId;
    public String name;
    public int age;
    public static String addr;  // static 직렬화 제외
    transient int point;        // transient 직렬화 제외
}


serializable-s1


직렬화의 주요 목적

  • 객체의 저장 및 전송: 객체를 파일에 저장하거나 네트워크를 통해 다른 시스템으로 전송할 때 사용
  • 데이터 유지: 객체의 상태를 보존하여 나중에 복원하거나 공유할 때 사용
  • 자바 직렬화의 활용: 데이터베이스에 객체를 저장하거나 분산 시스템 간에 객체를 전송하는 데에도 사용


객체 스트림

객체는 클래스에 정의된 인스턴스변수이 집합이다. 객체에는 클래스변수나 메서드가 포함되지 않고 객체에서는 오직 인스턴스변수들로만 구성되어 있다. 자바에서는 메모리에 생성 된 객체를 파일 또는 네트워크로 출력할 수 있는데 객체를 출력하려면 필드값을 일렬로 늘어선 바이트로 변경해야 한다. 이것을 직렬화(Serialization)라고 한다. 반대로 직렬화된 바이트를 객체의 필드값으로 복원하는 것을 역직렬화(deserialization)라고 한다.

이러한 직렬화, 역직렬화하는 것을 도와주는 보조스트림이 ObjectInputStream, ObjectOutputStream 이다.

ObjectInputStream objectIn = new ObjectInputStream("바이트 입력 스트림");
ObjectOutputStream objectOut = new ObjectOutputStream("바이트 출력 스트림");
//객체를 직렬화 할때 writeObject() 사용
objectOut.writeObject(obj);
//직렬화된 데이터를 역직렬화 해서 복원할 때 readObject() 사용
(객체타입) objectIn.readObject();



직렬화 예제

public class ExSerialization2Obeject {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        FileInputStream fis = new FileInputStream("/Users/linked2ev/Dev/eduapps/Playground4Java/user_goods.dat");
        ObjectInputStream ois = new ObjectInputStream(fis);

        ExUser user = (ExUser) ois.readObject();
        ExLoanProduct loanProduct = (ExLoanProduct) ois.readObject();

        ois.close();
        fis.close();

        System.out.println(user);
        System.out.println(loanProduct);
    }
}
ExUser{id=112, userId='linked2ev', name='김0준', age=34, cnt=0}
ExLoanProduct{id=52, name='XX 은행-직장인 신용대출', loanAmt=218000000}