티스토리 뷰

반응형

 

직렬화(Serializable)에 대해서 가볍게 살펴보겠습니다.

Effective Java 2/E에서 객체 직렬화 API에 대해서 이렇게 정의하고 있습니다.

바이트 스트림(byre stream)으로 인코딩(encoding)하거나, 바이트 스트림 인코딩에서 객체를 복원하는 프레임워크 입니다.

객체를 바이트 스트림으로 인코딩하는 것을 직렬화(serialization) 라고 하고, 그 반대는 역직렬화(deserialization) 입니다.

 

 

기본적인 직렬화 만드는 조건

 

기본적인 직렬화 조건은 java.io.Serializable 인터페이스를 상속받아야 합니다.

우아한형제들의 기술 블로그에서 가져온 소스를 기반으로 예를들면 다음과 같습니다.

 

package woowahan.blog.exam1;
/** 직렬화 할 회원 클래스 */
public class Member implements Serializable {
  private String name;
  private String email;
  private int age;

  public Member(String name, String email, int age) {
    this.name = name;
    this.email = email;
    this.age = age;
  }

  // Getter 생략
  @Override
  public String toString() {
    return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
  }
}

 

 

직렬화 방법

 

기본적인 자바 직렬화는 방법은 java.io.ObjectOutputStream 을 통해 생성할 수 있습니다.

직렬화 만드는 소스도 우아한형제들의 기술 블로그에서 가져온 소스를 기반으로 객체를 byte[] 로 변경하겠습니다.

public class SampleSerialization { 
    public static void main(String[] args) {
        Member member = new Member("김배민", "deliverykim@baemin.com", 25);
        byte[] serializedMember;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(member);
            // serializedMember -> 직렬화된 member 객체 
            serializedMember = baos.toByteArray();
            }
        }
        // 바이트 배열로 생성된 직렬화 데이터를 base64로 변환
        System.out.println(Base64.getEncoder().encodeToString(serializedMember));
    }
}

ObjectOutputStream 의 writeObject() 을 활용하여 역직렬화 하는 것을 확인 할 수 있습니다.

 

 

역직렬화 조건

 

역직렬화 조건은 크게 두가지로 나누면

  • 직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 합니다.

    • 중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 합니다.
  • 자바 직렬화 대상 객체는 동일한 serialVersionUID 을 가지고 있어야 합니다.

    private static final long serialVersionUID = <무작위로 고른 Long 값>;

    직렬 버전 UID 는 별도로 선언 안하면 자동으로 생성되어 위의 직렬화 생성 소스에는 생략하였습니다.

    직렬버전 UID를 지정하지 않았을 때 장점

    1.직렬버전 UID 때문에 생길 수 있는 잠재적 호환성 문제가 사라집니다.

    2.성능이 조금 개선되는 효과가 있습니다.

    직렬버전 UID를 지정하지 않았을 때 단점

    실행 시간에 UID을 만드느라 시간이 많이 걸리는 계산을 하게 됩니다.

    출처 : Effective Java 2/E

 

 

역직렬화

 

역직렬화 만드는 소스도 우아한형제들의 기술 블로그에서 가져온 소스를 기반으로 byte[] 을 객체로 변경하겠습니다.

// 직렬화 예제에서 생성된 base64 데이터 
String base64Member = "...생략";
byte[] serializedMember = Base64.getDecoder().decode(base64Member);
try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedMember)) {
  try (ObjectInputStream ois = new ObjectInputStream(bais)) {
  // 역직렬화된 Member 객체를 읽어온다.
  Object objectMember = ois.readObject();
  Member member = (Member) objectMember;
  System.out.println(member);
  }
}

ObjectInputStream 의 readObject() 을 활용하여 역직렬화 하는 것을 확인 할 수 있습니다.

 

 

마무리

 

직렬화(Serialization) 과 역직렬화에 대해서 간단히 살펴보았습니다.

간단히 정의하면 객체를 바이트 스트림으로 변화시키는 것이 직렬화이며, 직렬화된 바이트 스트림을 객체로 변화 시키는 것이 역직렬화 입니다.

서블릿 세션, 캐시, 자바 RMI(Remote Method Invocation) 등 다양한 부분에서 활용되고 있는 기술로 기억하면 좋을거 같습니다.

 

 

참고

 

자바 직렬화, 그것이 알고싶다. 훑어보기편

도서 : Effective Java 2/E

반응형

'프로그래밍 > Java' 카테고리의 다른 글

Java Transient 에 대해서 알아보자.  (0) 2020.06.16
DI(의존성주입) 은 무엇인가?  (0) 2018.07.14
[Java]enum을 이용한 for-each 문  (0) 2017.12.18
[Java]직렬화(Serializable)  (0) 2017.12.18
댓글