직렬화의 기능적 의미
public interface Serializable {
}
Serializable 의 인터페이스를 보면 메소드가 하나도 없다.
구현해야 할 메소드가 없는데 왜 있는것일까?
개발을 하다 보면 아래와 같은 경우가 존재합니다.
- 생성한 객체를 파일로 저장할 일이 있을 수도 있습니다.
- 저장한 객체를 읽을 일이 생길 수도 있습니다.
- 다른 서버에서 생성한 객체를 받을 일도 생길 수 있습니다.
이럴 때 꼭 필요한 것이 Serializable 입니다. 우리가 만든 클래스가 파일에 읽거나 쓸 수 있도록 하거나, 다른 서버로 보내거나 받을 수 있도록 하려면 반드시 이 인터페이스를 구현해야 합니다.
** Serializable 인터페이스를 구현하면 JVM에서 해당 객체는 저장하거나 다른 서버로 전송할 수 있도록 해준다.
그래서 직렬화가 무엇인가?
- 자바 직렬화란 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)을 아울러서 이야기합니다.
- 시스템적으로 이야기하자면 JVM(Java Virtual Machine 이하 JVM)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 같이 이야기합니다.
Serializable 인터페이스를 구현한 클래스들을 보면 serialVersionUID라는 값을 지정해주는 것을 본 적이 있을 것입니다.
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
private static final long serialVersionUID = 362498820763181265L;
}
예를들어, HashMap 클래스를 보면 위와 같은 변수를 볼 수 있습니다.
이렇게 Serializable 인터페이스를 구현한 후에는 위와 같이 serialVersionUID라는 값을 지정해 주는 것을 권장합니다.
(만약 별도로 지정하지 않으면, 자바 소스가 컴파일될 때 자동으로 생깁니다.)
static final long serialVersionUID = 1L;
위와 같이 반드시 static final long으로 선언해야 하며, 변수명도 serialVersionUID로 선언해 주어야 자바에서 인식을 할 수 있습니다.
그러면 이 값은 어디에 사용되고 어떤 값을 넣어야 할까요?
- 값은 아무런 값이나 지정해주면 됩니다.
값의 의미는 해당 객체의 버전을 명시하는 데 사용합니다. 예를들어 보겠습니다.
A라는 서버에서 B라는 서버로 SerialDTO라는 클래스의 객체를 전송한다고 가정하겠습니다. 전송하는 A 서버에 SerialDTO라는 클래스가 있어야 하고, 전송받는 B 서버에는 SerialDTO라는 클래스가 있어야만 합니다.
그래야만 그 클래스의 객체임을 알고 데이터를 받을 수 있습니다.그런데 만약 A 서버가 갖고 있는 SerialDTO에는 변수가 3개 있고, B 서버의 SerialDTO에는 변수가 4개 있는 상황이 발생하면 어떻게 될까요?
이러면 자바에서는 제대로 처리를 못하게 됩니다. 따라서 각 서버가 쉽게 해당 객체가 같은지 다른지를 확인할 수 있도록 하기 위해서는 serialVersionUID로 관리를 해주어야만 합니다.즉 클래스 이름이 같더라도 이 ID가 다르면 다른 클래스라고 인식합니다. 게다가, 같은 UID라고 할지라도, 변수의 개수나 타입 등이 다르면 이 경우도 다른 클래스로 인식합니다.
'IT > Java' 카테고리의 다른 글
Java Client 로 Keycloak API 사용하기 (0) | 2022.12.20 |
---|