serializable
는 인터페이스 입니다. 동시에 Java의 직렬화 기능
을 지원합니다.
여기서 직렬화란, 객체를 바이트 스트림(01101001...)으로 변환
하여 파일에 저장하거나 네트워크를 통해 전송할 수 있게 하는 기술입니다.
Serializable를 구현하는 목적은 크게 3가지입니다.
1번에 대해서는 이미 설명한 부분이기 때문에 넘어가겠습니다.
2번의 경우 직렬화된 객체는 클래스의 버전 정보
를 포함합니다. 왜냐하면 객체를 역직렬화할 때 클래스 버전이 호환
되는지 확인하기 위해서입니다.
예를 들어 필드 추가, 삭제, 수정의 경우 클래스의 구조가 변경될 수 있고, 메소드 변경과 상속구조의 변경 또한 클래스의 구조가 변경됩니다.
따라서 데이터의 무결성이 깨질 수 있기 때문에, 특정 고유 식별자
로 항상 호환성을 유지시켜야 합니다.
따라서 클래스 버전이 호환
되는지 반드시 체크를 해야되고, 이에 따라 Serializable 인터페이스를 사용하는 것입니다.
그래서 Serializable
을 사용하면 Java 16부터는 @Serial
이라는 어노테이션을 이용해서 serialVersionUID
라는 고유 식별자로 클래스의 버전을 표현합니다.
public class SerializableExample implements Serializable { // 클래스의 버전관리를 위해
@Serial
private static final long serialVersionUID = 1L; // 고유식별자 필드
.
.
아래의 코드의 의미를 생각해보겠습니다. 이 의미는 추상클래스 BaseEntity를 상속하는 클래스의 타입
은 Serializable을 implements한 타입
이라는 의미입니다. 또한 BaseEntity는 Serializable을 implements했기 때문에 고유식별자를 가질 수 있게 됩니다.
public abstract class BaseEntity<I extends Serializable> implements Serializable {}
객체를 직렬화하면, 해당 객체를 다른 시스템 또는 프로세스로 전송할 수 있습니다. 이는 분산 환경에서 다수의 시스템 간에 객체를 교환하거나 공유할 때 유용합니다.
실무에서 Serializable을 사용하는 이유와 제 기준에서 Serializable을 사용하는 이유는 클래스 버전관리를 통한 데이터의 무결성 보완
이라는 가장 큰 이유가 있습니다. 이는 낙관적 락
과 비관적 락
과 관련이 있습니다.
제 기준 나머지 객체의 저장 및 전송, 분산 환경에서의 사용은 부가적인 이유입니다.