https://en.wikipedia.org/wiki/Serialization
In computing, serialization (US spelling) or serialisation (UK spelling) is the process of translating a data structure or object state into a format that can be stored (for example, in a file or memory data buffer) or transmitted (for example, across a computer network) and reconstructed later (possibly in a different computer environment).
위키피디아에서, 직렬화에 대한 설명을 찾아보면 위와 같이 설명하는데 번역하자면 serialization 은 데이터 구조나 객체를 저장(파일이나 memory data buffer) 하기 위한 형태(format) 혹은 전달가능한 형태로(네트워크를 통한)바꾸는 과정을 뜻한다. 그리고 직렬화된 데이터 format은 추후에 다른 컴퓨터 환경에서도 다시 본래의 데이터 구조나 객체로 재조립 될 수 있다. 정도로 의역할 수 있다.
조금 더 쉽게 설명하자면 자바 프로그램에서 데이터를 저장하거나 전송할 때 스트림 형태로 저장하고 전송하게 되는데, 객체를 스트림형태로 만드는 과정을 '직렬화' 라고 할 수 있겠다.
그럼 왜 스트림 형태로 만드는걸까라는 의문이 들 수 있을텐데 어쨋든 컴퓨터는 이진수 체계를 따르니, 객체를 객체 그대로 전달할 수 없는 문제가 있다. 1과 0으로 객체를 표현하기 위해서는 약속이 필요할 것이고, 그 약속을 스트림이라고 생각하고 넘어가자. (확실한 정보는 아니고, 개인적인 생각입니다... 틀린 부분이 있다면 말씀해주세요 ! )
그렇다면 어떻게 직렬화를 활용할 수 있는지 코드를 통해 알아보자
public class ObjectOutPutExample {
public static void main(String[] args) throws FileNotFoundException {
try(
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("outputExample.dat"));
)
{
out.writeObject(new GregorianCalendar(2020,10,18));
out.writeObject(new GregorianCalendar(2020,10,19));
out.writeObject(new GregorianCalendar(2020,10,20));
} catch (IOException ioe){
ioe.printStackTrace();
}
}
}
(참고 : Java 8 부터 지원하는 try-with-resource 문을 통해 자동으로 자원을 해제하였다)
ObjectOutputStream 의 writeObject() 메소드는 파라미터로 넘겨준 객체를 스트림으로 만들어 출력하는 메소드이다. 여기서, 근데 중요한 것은 바로 GregorianCalendar 클래스는 직렬화가 가능한 클래스란 점이다. 그렇다면 직렬화가 가능한 클래스는 어떻게 만들 수 있는 것일까?
한번 살펴보도록 하자.
GregorianCalendar 는
public class GregorianCalendar extends Calendar {}
Calendar 를 상속받은 클래스 였다. 그렇다면 Calendar 로 가보자.
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {}
Calendar 는 추상클래스인데 살펴보면 Serializable 이란 interface 를 구현하고 있다. 바로 이 Serializable 을 구현한 클래스들이 직렬화가 가능한 클래스이다.
아주 간단하게 Serializable 인터페이스를 구현하기만 하면 해당 클래스는 직렬화가 가능해지는 것이다.
그렇다면 Serializable 을 구현하지 않고 스트림으로 넣어 출력하려면 어떻게 될까?
간단하게 Person 이란 클래스를 만들어 보았다.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
그리고 앞서했던 방법과 같은 방법으로 스트림을 출력하려해보았다.
public class ObjectOutputExample2 {
public static void main(String[] args) throws FileNotFoundException {
try(
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("outputExample2.dat"));
)
{
out.writeObject(new Person("jaden", 10));
} catch (IOException ioe){
ioe.printStackTrace();
}
}
}
그러자, 당연스럽게도 에러가 떨어졌는데 해당 에러는 바로
java.io.NotSerializableException: serialization.Person
다음과 같았다. 해결하기 위해서 밑에와 같이 Person 클래스에서 Serializable 인터페이스를 구현했더니, 에러없이 잘 수행되었다.
public class Person implements Serializable{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
객체를 직렬화하여 stream 형태로 바꾸었다면, 다시 객체 형태로 바꾸는 작업 역시 필요하다. 이를 바로 역직렬화 라고 하는 것이다.
[도움을 얻은 곳]