직렬화(Serialization)라는 것은 자바 시스템 내부에 생성된 객체를 파일 또는 네트워크로 전송할 수 있는데, 이때, 객체를 외부 시스템에서 사용할 수 있도록 바이트 형태로 데이터를 변환하는 기술을 의미하며, 또한 바이트로 변환된 데이터를 객체로 변환하는 기술을 역직렬화(Deserialization)라고 합니다.

자바에서는 보조 스트림을 활용하여 직렬화를 제공하는데, 이 보조 스트림은 ObjectInputStreamObjectOutputStream이며, 객체를 입출력할 수 있습니다.

ObjectInputStream(InputStream in)은 바이트 입력 스트림과 연결되어 객체로 역직렬화하는 역할이며, ObjectOutputStream(OutputStream out)은 바이트 출력 스트림과 연결되어 객체를 직렬화하는 역할을 합니다.

Serializable 인터페이스

자바는 Serializable 인터페이스를 구현한 클래스만 직렬화할 수 있도록 제공하며, 필드나 메서드가 없는 빈 인터페이스지만 객체를 직렬화할 때, private 필드를 포함한 모든 필드를 바이트로 변환해도 좋다는 표시 역할을 합니다.

public class A implements Serializable { ... }

객체를 직렬화하면 바이트로 변환되는 것은 필드들인데, 모든 필드가 직렬화 대상이 되지 않으며, static 또는 transient가 붙은 경우 직렬화가 되지 않습니다.

public class A implements Serializable { 
	int value1; // 직렬화 O
    static int value2; // 직렬화 X
    transient int value3;  // 직렬화 X
}

Serializable 인터페이스를 구현한 클래스를 컴파일하면 자동적으로 serialVersionUID 정적 필드가 추가 됩니다.

serialVersionUID 필드

직렬화된 객체를 역직렬화할 때 직렬화했을 때 같은 클래스를 사용해야 합니다

여기서 serialVersionUID 필드는 같은 클래스임을 알려주는 식별자 역할을 합니다.

여기서, 직렬화하여 전송하는 경우, 보내는 쪽과 받는 쪽 모두 같은 serialVersionUID를 갖는 클래스를 가지고 있어야 하는데 한 쪽에서 클래스를 변경해서 재컴파일하면 다른 serialVersionUID를 갖게 되어 역직렬화에 실패할 수 있게 됩니다.

public class A implements Serializable { 
	static final long serialVersionUID = 정수값;
}

클래스에 위 코드와 같이 serialVersionUID 필드가 명시적으로 선언되어 있으면 동일한 serialVersionUID 값을 유지할 수 있습니다.

serialVersionUID 값은 클래스마다 다른 값을 갖도록 하는 것이 좋습니다.

이상으로 자바에서 사용하는 직렬화에 대해서 간단히 알아봤습니다.

profile
꾸준함으로 성장하는 개발자 지망생

0개의 댓글