프로그래밍/JAVA

[ JAVA ] 직렬화란

리신 2023. 4. 25. 23:19
반응형

객체를 저장하거나 메모리, 데이터베이스 혹은 파일로 옮기려면 어떻게 해야할까?

이럴 때 필요한 것이 직렬화다. 

 

직렬화란?

직렬화란 객체를 데이터 스트림으로 만드는 것을 뜻한다.

즉 객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 작업을 말한다.

 

솔직히 이렇게 말하면 어려운것 같다..

 

쉽게 말하면, 직렬화란 현재 데이터의 상태를 영속적으로 저장하거나

다른 환경으로 전달(네트워크 통신 등)하기 위해 어떠한 정해진 포맷으로 변환하는 과정을 말한다.

그리고 이 변환된 데이터를 다시 원래 데이터로 변환 가능하며, 이러한 과정을 역직렬화라고 한다.

 

그리고 자바에서는 직렬화란?

자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)을 아울러서 말한다.

 

시스템 적으로는 JVM(Java Virtual Machine)의 메모리에 상주(heap 또는 stack) 되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 말한다.

 


ObjectInputStream, ObjectOutputStream

직렬화에는 ObjectOutputStream을 사용하고, 역직렬화에는 ObjectInputStream을 사용한다.

각각은 OutputStream과 InputStream을 직접 상속받지만 기반스트림을 필요로 하는 보조 스트림이므로 객체 생성시 입출력할 스트림을 지정해주어야 한다.

 

예시)

만약 파일에 객체를 저장(직렬화)하고 싶다면 아래와 같이 하면된다.

 

FileOutputStream fos = new FileOutputStream("objectfile.ser");
ObjectOutStream out = new ObjectOutStream(fos);

out.writeObject(new UserInfo());

위 코드는 objectfile.ser 이라는 파일에 UserInfo 객체를 직렬화 하여 저장한다.

출력할 스트림(FileOutpu tStream)을 생성해서 이를 기반스트림으로 하는 ObjectOutputStream을 생성한다.

ObjectOutStream의 writeObject(Object obj)를 사용해서 객체를 출력하면,

객체가 파일에 직렬화되어 저장된다.

 

역직렬화 방법도 간단하다.

직렬화할 때와는 달리 입력스트림을 사용하고 writeObject(Object obj)대신 readObject()를 사용하여 저장된 데이터를

읽기만 하면 객체로 역직렬화 된다.


직렬화 가능한 클래스 만들기 - Serializable, transient

직렬화하고자하는 클래스가 java.io.Serializable인터페이스를 구현하도록 하면 직렬화가 가능한 클래스를 만들 수 있다.

조상이 Serializable인터페이스를 구현하였다면 자손 클래스도 직렬화가 가능하다.

 

public class UserInfo implements Serializable{
    Object obj = new Object(); // 직렬화 불가능
    Object obj = new String("abc"); // 직렬화 가능
}

Object 객체는 직렬화할 수 없지만, 실제로 저장된 객체가 직렬화가 가능하다면 직렬화를 수행할 수 있다.

 

transient

직렬화하고자 하는 객체의 클래스에 직렬화가 안 되는 객체에 대한 참조를 포함하고 있다면,

제어자 transient를 붙여서 직렬화 대상에서 제외할 수 있다.

public class UserInfo implements Serializable {
  String name;
  transient String password;  // 직렬화 대상에서 제외
  int age;
  transient Object obj = new Object();  // 직렬화 대상에서 제외

 


직렬화가능한 클래스의 버전관리

직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스를 사용해야한다.

그러나 클래스의 이름이 같더라도 내용이 변경된 경우에는 역직렬화에 실패하기 때문에 버전을 일치시켜야 한다.

객체를 직렬활 할 때 serialVersionUID라는 클래스 버전을 자동생성해서 직렬화 내용에 포함한 뒤,

역직렬화 할 때 클래스의 버전을 비교할 수 있게 한다.

 

그러나 static변수나 상수 또는 transient가 붙은 인스턴스변수가 추가되는 경우에는 직렬화에 영향을 미치지 않기 때문에

클래스의 버전을 다르게 인식하도록 할 필요는 없다.

 

 

 

 

 

참고자료 : 자바의 정석, 우아한형제들 기술블로그

https://techblog.woowahan.com/2550/

 

자바 직렬화, 그것이 알고싶다. 훑어보기편 | 우아한형제들 기술블로그

{{item.name}} 자바의 직렬화 기술에 대한 대한 이야기입니다. 간단한 질문과 답변 형태로 자바 직렬화에 대한 간단한 설명과 직접 프로젝트를 진행하면서 겪은 경험에 대해 이야기해보려 합니다.

techblog.woowahan.com

 

반응형

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

[ JAVA ] 네트워킹 (Networking)  (0) 2023.04.25
[ JAVA ] 입출력  (0) 2023.04.05
[ JAVA ] 쓰레드란?  (0) 2023.02.21
[JAVA] Properties 란?  (0) 2023.01.31
[JAVA] TreeMap 이란  (0) 2023.01.29