JAVA/포스팅

자바 직렬화(Serialization)

짜집퍼박사(짜박) 2023. 11. 26. 22:14

자바 직렬화(Java Serialization)는 객체의 상태를 바이트 스트림으로 변환하여 저장하거나 네트워크를 통해 전송하는 메커니즘을 말합니다. 이를 통해 객체의 상태를 저장하고 나중에 복원할 수 있습니다. 주로 객체를 파일에 저장하거나 네트워크를 통해 객체를 전송하는데 사용됩니다.

 

직렬화의 기본 원리

직렬화는 java.io.Serializable 인터페이스를 구현한 클래스에서 사용됩니다. 이 인터페이스는 특별한 메서드를 갖지 않고 단순히 마킹 인터페이스로 사용됩니다. 직렬화가 가능한 클래스는 다음의 조건을 충족해야 합니다.

 

1. Serializable 인터페이스를 구현해야 합니다.
2. 모든 필드는 Serializable이어야 합니다. 만약 직렬화하고자 하는 클래스에 포함된 필드 중 하나라도 Serializable을 구현하지 않은 경우 NotSerializableException이 발생합니다.

 

직렬화는 객체를 스트림으로 변환하는 과정이고, 역직렬화는 스트림에서 객체로 복원하는 과정입니다.

 

 

직렬화 예제

다음은 간단한 직렬화 및 역직렬화의 예제입니다.

import java.io.*;

// 직렬화 가능한 클래스
class MyClass implements Serializable {
    private static final long serialVersionUID = 1L; // 직렬화 버전 UID
    private int intValue;
    private String stringValue;

    // 생성자 및 메서드들...

    // 직렬화 가능한 클래스에서 사용되는 메서드들...
}

public class SerializationExample {
    public static void main(String[] args) {
        // 직렬화
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.ser"))) {
            MyClass myObject = new MyClass(42, "Hello, Serialization!");
            oos.writeObject(myObject);
            System.out.println("Object serialized successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 역직렬화
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"))) {
            MyClass restoredObject = (MyClass) ois.readObject();
            System.out.println("Object deserialized successfully.");
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

 

 

직렬화에서 고려할 사항

 

1. 직렬화 버전 UID

클래스의 직렬화 버전 UID(serialVersionUID)는 직렬화된 객체의 버전을 식별하는 데 사용됩니다. 명시적으로 선언하지 않으면 JVM이 자동으로 생성합니다. 만약 직렬화 후 클래스가 변경되면 serialVersionUID를 명시적으로 선언하는 것이 좋습니다.

private static final long serialVersionUID = 1L;

2. transient 키워드

transient 키워드를 사용하면 특정 필드를 직렬화에서 제외할 수 있습니다. 예를 들어, 보안 상 민감한 정보가 있는 경우 이를 직렬화에서 제외하는 데에 활용할 수 있습니다.

private transient String sensitiveData;

3. 직렬화 커스터마이징

writeObject() 및 readObject() 메서드를 사용하여 객체의 직렬화 및 역직렬화 과정을 사용자 지정할 수 있습니다. 이를 통해 특정 필드의 값을 가공하거나 특별한 처리를 할 수 있습니다.

private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject();
    // 추가적인 직렬화 로직
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    // 추가적인 역직렬화 로직
}

4. 직렬화의 보안 고려사항

직렬화는 객체의 상태를 외부에 저장하므로 보안에 민감한 정보를 포함한 클래스를 직렬화할 때에는 신중해야 합니다. 직렬화된 데이터를 역직렬화할 때는 신뢰할 수 있는 소스에서만 데이터를 받아야 합니다.

 

5. Externalizable 인터페이스

Externalizable 인터페이스를 구현하면 writeExternal() 및 readExternal() 메서드를 통해 직렬화 및 역직렬화 프로세스를 완전히 사용자 지정할 수 있습니다.

class MyExternalizableClass implements Externalizable {
    // 필드 및 메서드들...

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        // 직렬화 로직
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        // 역직렬화 로직
    }
}

직렬화는 자바에서 매우 유용한 기술이지만, 주의를 기울여 사용해야 하며 특히 보안과 관련된 클래스를 직렬화할 때는 신중해야 합니다.

 

With ChatGPT

'JAVA > 포스팅' 카테고리의 다른 글

자바 ObjectOutputStream  (0) 2023.11.26
자바 ObjectInputStream  (0) 2023.11.26
자바 File  (0) 2023.11.26
자바 RandomAccessFile  (0) 2023.11.26
자바 표준입출력 setIn()  (0) 2023.11.26