직렬화는 Java에서 주로 사용되는 것으로 알고 있지만, Scala나 Akka에서도 사용된다. 그렇다면 직렬화가 무엇인지 정리할 예정이다.
객체를 저장하거나 메모리, DB 혹은 파일로 옮기려면 직렬화
과정을 거쳐야 한다. 직렬화란 객체를 바이트 스트림으로 바꾸는 것으로, 객체에 저장된 데이터를 스트림에 write하기 위해 연속적인(serial) 데이터로 변환하는 것을 뜻한다.
직렬화의 주된 목적은 객체를 상태 그대로 저장하고 필요할 때 다시 생성하여 사용
하는 것이다.
역직렬화(deserialization)는 직렬화의 반대말로, 네트워크나 영구저장소에서 바이트 스트림을 가져와서 객체가 저장되었던 그 상태로 변환하는 것이다.
위는 직렬화와 역직렬화를 도식화한 이미지이다. 객체를 직렬화하여 바이트스트림이 생성된다. 이때 생성된 바이트 스트림은 플랫폼에 독립적이다. 따라서 직렬화된 객체가 DB나 메모리, 파일 등에 저장되고 외부 프로그램에서 이를 저장된 상태 그대로 역직렬화 하여 사용할 수 있다.
그렇다고 모든 객체를 직렬화할 수는 없다. Scala에서는 Serializable
이라는 trait를 확장시키고, @SerialVersionUID
어노테이션을 사용해야 한다.
@SerialVersionUID(100L)
class Stock(var symbol: String, var price: BigDecimal)
extends Serializable {
// code here ...
}
위와 같은 형태로 클래스를 직렬화할 수 있다. 이때, Serializable
은 trait이므로 믹스인할 수 있다.
클래스를 직렬화할 수 있도록하면, Java에서 직렬화한 객체처럼 사용할 수 있다. 심지어 deep copy
같은 기술들도 사용할 수 있다.
그렇다면, SerialVersionUID
는 무엇일까? 직렬화된 객체를 역직렬화 할 땐 직렬화 당시 클래스와 같은 클래스를 사용해야 한다. 즉, 클래스명이 같더라도 내용이 변경된 경우 역직렬화는 실패한다. 따라서 버전 정보를 제공함으로써 클래스 내용이 변경되더라도 역직렬화를 할 수 있다. 따라서 직렬화 시에는 SerialVersionUID
를 사용할 것을 권장한다.