본문 바로가기
Programming/Java

Java의 객체 직렬화 : 외부화와 차이점

by Devsaurus 2024. 1. 14.
728x90

Java의 객체 직렬화

Java의 객체 직렬화는 객체의 상태를 바이트 스트림으로 변환하는 프로세스로, 이를 통해 객체를 쉽게 파일에 저장하거나 네트워크를 통해 전송하거나 데이터베이스에 유지할 수 있습니다. 

역직렬화 프로세스는 바이트 스트림에서 객체를 재구성합니다.


java.io.Serialized 인터페이스는 클래스가 직렬화될 수 있음을 나타내는 데 사용되는 마커 인터페이스입니다.

클래스가 '직렬화 가능'을 구현하면 해당 인스턴스는 Java에 내장된 직렬화 메커니즘을 사용하여 직렬화 및 역직렬화될 수 있습니다.

객체 직렬화를 사용하는 이유

1. 지속성: 나중에 검색할 수 있도록 객체 상태를 파일이나 데이터베이스에 저장하기 위해 객체를 직렬화합니다.

 

2. 통신: 네트워크 통신을 위해 개체를 직렬화하여 응용 프로그램이나 분산 시스템 간에 개체를 전송할 수 있습니다.

 

3. 캐싱: 객체를 직렬화하여 상태를 캐시하므로 데이터를 다시 계산하거나 다시 가져올 필요성이 줄어듭니다.

 

4. 딥 카피(Deep Copy): 직렬화 및 역직렬화를 통해 객체의 딥 카피를 생성하여 객체를 효과적으로 복제합니다.

직렬화의 예

import java.io.*;

public class SerializationExample {
    public static void main(String[] args) {
        // Creating an object to be serialized
        MyClass myObject = new MyClass(42, "Hello, Serialization!");

        // Serialization
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.ser"))) {
            oos.writeObject(myObject);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Deserialization
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"))) {
            MyClass deserializedObject = (MyClass) ois.readObject();
            System.out.println(deserializedObject);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class MyClass implements Serializable {
    private int intValue;
    private String stringValue;

    public MyClass(int intValue, String stringValue) {
        this.intValue = intValue;
        this.stringValue = stringValue;
    }

    @Override
    public String toString() {
        return "MyClass{" +
               "intValue=" + intValue +
               ", stringValue='" + stringValue + '\'' +
               '}';
    }
}

 

객체 외부화

 

객체 외부화는 Java에서 제공하는 직렬화의 대안으로 직렬화 프로세스를 더 효과적으로 제어할 수 있습니다. 

이는 Serialize를 확장하는 java.io.Externalized 인터페이스를 구현함으로써 달성됩니다. 

직렬화 가능과 달리 외부화에는 직렬화 프로세스를 사용자 정의하기 위해 writeExternal 및 readExternal 메소드의 명시적인 구현이 필요합니다.

 

직렬화와 외부화의 차이점

1. 직렬화 제어

  • 직렬화: 프로세스에 대한 통제력이 덜한 자동 직렬화/역직렬화입니다.
  • 외부화: writeExternal 및 readExternal 메소드를 구현하여 직렬화 프로세스를 사용자 정의합니다.

2. 기본 직렬화와 사용자 정의 직렬화

  • 직렬화: 대부분의 클래스에 대해 기본 직렬화 메커니즘을 사용합니다.
  • 외부화: 모든 필드에 대해 직렬화 논리를 명시적으로 구현해야 합니다.

3. 현장 통제

  • 직렬화: 모든 비일시적 필드는 자동으로 직렬화됩니다.
  • 외부화: 사용자 정의 논리를 기반으로 필드의 선택적 직렬화를 허용합니다.

4. 성능

  • 직렬화: 자동 직렬화의 오버헤드로 인해 일반적으로 성능이 떨어집니다.
  • 외부화: 개발자가 직렬화 프로세스를 더 효과적으로 제어할 수 있으므로 신중하게 구현하면 성능이 더 높아질 수 있습니다.

 

외부화의 예

import java.io.*;

public class ExternalizationExample {
    public static void main(String[] args) {
        // Creating an object to be externally serialized
        ExternalizedClass externalizedObject = new ExternalizedClass(42, "Hello, Externalization!");

        // Externalization
        try (ObjectOutput oo = new ObjectOutputStream(new FileOutputStream("externalizedObject.ser"))) {
            externalizedObject.writeExternal(oo);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Deserialization
        ExternalizedClass deserializedObject = new ExternalizedClass();
        try (ObjectInput oi = new ObjectInputStream(new FileInputStream("externalizedObject.ser"))) {
            deserializedObject.readExternal(oi);
            System.out.println(deserializedObject);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class ExternalizedClass implements Externalizable {
    private int intValue;
    private String stringValue;

    public ExternalizedClass() {
        // Required no-argument constructor for Externalizable
    }

    public ExternalizedClass(int intValue, String stringValue) {
        this.intValue = intValue;
        this.stringValue = stringValue;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        // Custom serialization logic
        out.writeInt(intValue);
        out.writeUTF(stringValue);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        // Custom deserialization logic
        intValue = in.readInt();
        stringValue = in.readUTF();
    }

    @Override
    public String toString() {
        return "ExternalizedClass{" +
               "intValue=" + intValue +
               ", stringValue='" + stringValue + '\'' +
               '}';
    }
}

 

마무리

요약하면 Java의 객체 직렬화를 통해 객체를 쉽게 저장, 전송 또는 유지할 수 있습니다. 

직렬화와 외부화 간의 선택은 직렬화 프로세스 중에 필요한 제어 및 사용자 정의 수준에 따라 달라집니다. 

외부화는 더 많은 제어를 제공하지만 명시적인 요구가 필요합니다.

728x90