경계의 경계

자바의 직렬화 (Serialization) 본문

Java

자바의 직렬화 (Serialization)

gigyesik 2024. 2. 22. 02:49

직렬화 (Serialization) 이란 무엇인가

직렬화란 객체 (Object) 를 바이트 (byte) 단위로 변환하는 과정이고, 역직렬화 (Deserialization) 는 반대로 바이트 데이터를 객체로 변환하는 과정이다.

  • 직렬화가 필요한 이유는 자바 객체가 플랫폼 독립적이지 않기 때문이다. 바이트 스트림으로 표현된 데이터는 어떤 플랫폼에서도 읽을 수 있다.
  • 자바로 직렬화를 구현하기 위해서는 java.io.Serializable 을 implement 한다.
  • writeObject(), readObject() 메서드를 사용한다.

직렬화의 장점

  • 객체의 상태를 보존할 수 있다.
  • 객체를 네트워킹의 대상으로 사용할 수 있다.

직렬화시 유의점

  • 부모 클래스에서 Serializable을 상속한 경우 자식 클래스에서는 상속이 필수가 아니다.
  • 자식 클래스에서 Serializable을 상속한 경우 부모 클래스에서는 필수적으로 상속해야 한다.
  • non-static 데이터만이 직렬화될 수 있다.

직렬화시 특징

  • transient 키워드 변수 : 직렬화시 무시된다. 역직렬화하면 변수에 할당되는 기본값이 출력된다.
  • static 키워드 변수 : 직렬화되지 않고, 역직렬화시 객체가 가지고 있는 현재값이 출력된다.
  • final 키워드 변수 : 바로 초기화되어 직렬화, 역직렬화된다.
  • transient static, transient final 키워드에서의 transient는 무시된다.
    • static은 객체와 관련없이 메모리에 할당되어있기 때문이고
    • final은 변수의 값을 바로 초기화하기 때문이다

직렬화 예시

public class SerializationTest2 implements Serializable {
    private static final long serialversionUID = 123456789L;

    transient int a;
    static int b;
    int c;
    String d;
    transient final int e = 40;

    public SerializationTest2(int a, int b, int c, String d) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }

    public static void main(String[] args) {
        SerializationTest2 serializationTest2 = new SerializationTest2(10, 20, 30, "Test");
        String fileName = "fileTest";

        // 직렬화
        try {
            FileOutputStream file = new FileOutputStream(fileName);
            ObjectOutputStream output = new ObjectOutputStream(file);

            output.writeObject(serializationTest2);

            output.close();
            file.close();

            System.out.println("Serialized");
            System.out.println(serializationTest2.a); // 10
            System.out.println(serializationTest2.b); // 20
            System.out.println(serializationTest2.c); // 30
            System.out.println(serializationTest2.d); // Test
            System.out.println(serializationTest2.e); // 40

            serializationTest2.b = 50; // static 데이터 변경
        } catch (IOException e) {
            System.out.println("Not Serialized");
        }

        serializationTest2 = null;

        // 역직렬화
        try {
            FileInputStream file = new FileInputStream(fileName);
            ObjectInputStream output = new ObjectInputStream(file);

            serializationTest2 = (SerializationTest2) output.readObject();

            output.close();
            file.close();

            System.out.println("Deserialized");
            System.out.println(serializationTest2.a); // 0. transient 데이터는 직렬화되지 않음
            System.out.println(serializationTest2.b); // 50. static 데이터
            System.out.println(serializationTest2.c); // 30
            System.out.println(serializationTest2.d); // Test
            System.out.println(serializationTest2.e); // 40

        } catch (IOException | ClassNotFoundException e) {
            System.out.println("Not Deserialized");
        }
    }
}

Resources

'Java' 카테고리의 다른 글

자바의 제네릭 (Generic)  (1) 2024.02.28
자바의 네트워킹과 소켓 통신  (1) 2024.02.27
자바의 Collection Framework  (1) 2024.02.20
자바의 메모리 관리  (1) 2024.02.13
자바의 HTTP 통신 라이브러리  (0) 2024.02.09