Backend/Java

직렬화

간지나제 2021. 6. 12. 16:06

Java 내부 시스템에서 사용되는 객체나 데이터를 외부에서 사용할 수 있도록 Byte 형태로 변환하는 것을 의미한다.
프로그램 데이터들이 연속적으로 있지 않고 내부 포인터에 의해 참조되고 있는데 이 데이터들을 한데 모아 다른 곳에서도 쓸 수 있도록 연속적(serial)인 형태로 변환하는 것

  • 대부분 OS의 프로세스 구현은 서로 다른 가상메모리주소공간(Virtual Address Space)를 갖기 때문에 Object 타입의 참조값(주소값) 데이터 인스턴스를 전달 할 수 없다.
    그렇기 때문에 서로 다른 메모리 공산 사이의 데이터 전달을 위해서는 메모리 공간의 주소값이 아닌 Byte 형태로 변환된 객체 데이터를 전달하면, 사용하는 쪽에서 역직렬화하여 사용할 수 있다.
    즉, 전송/저장 가능한 데이터를 만드는 것이 직렬화(Serialization)이다.

  • JSON, CSV 등의 포맷은 직렬화/역직렬화 시에 특정 라이브러리를 도입해야 쉽게 개발이 가능하며, Java직렬화는 java.io.Serializable (마커)인터페이스만 구현해주면 기본 Java 라이브러리만 사용해도 직렬화/역직렬화가 가능하다.

  • Transient 가 선언된 멤버는 전송되지 않는다. (보통 해당 데이터를 전송하고 싶지 않을 때 적용한다. 예를 들어, 보안 정보같은 경우도 해당할 수 있다.)

class serializationTest implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private String address;
    prviate transient String hobby;
}

serialVersionUID를 관리하는 이유는 ?

  • Java 직렬화 대상 객체는 동일한 serialVersionUID 를 가지고 있어야한다.
  • 선언하지 않아도 내부적으로 자동으로 생성된 해쉬값이 할당된다.
  • 멤버 변수가 추가되거나 삭제되면 serialVersionUID는 달라진다.
  • 역직렬화 할 때 기존의 serialVersionUID 와 변경된 serialVersionIUID가 다르면 java.io.InvalidClassExeption 예외가 발생한다.
  • 그러므로 직접 serailVersionUID를 관리해야 클래스가 변경되어도 문제없이 직렬화/역직렬화를 할 수 있다.
  • 하지만 serialVersionUID가 같다고 해서 무조건 직렬화/역직렬화를 할 수 있는 건 아니다.
    • 클래스의 멤버 타입이 같아야하고
    • 멤버 변수를 제거하거나 변수명을 바꾸면 해당 데이터는 누락된다.

https://ryan-han.com/post/java/serialization/
https://velog.io/@hellonewtry/자바-직렬화란-serialVersionUID-란
https://weicomes.tistory.com/63
https://hub1234.tistory.com/26

'Backend > Java' 카테고리의 다른 글

람다식(Lambda Expression), 람다란(Lambda)?  (0) 2022.08.12
Reflection(리플렉션)  (0) 2022.08.08
추상클래스와 인터페이스  (0) 2021.06.11
try-with-resources  (1) 2021.06.08
Generics  (0) 2021.04.27