JAVA - Serializable

1 minute read

Serializable은 왜 사용하는가?

자바의 직렬화 기능을 사용하는 객체를 명시적으로 알려준다. 이것을 안쓰면 직렬화가 안된다. 라고 알고 있었는데

이 기회에 알아보려고 좀 찾아봤다.

 

 

기존에는이 객체는 데이터 오브젝트이다 라는 것을 명시하기 위해 사용했었다. ajax, rest api 등등에 사용하는 DTO(VO..) 객체에 그냥 붙였다. gson/jackson을 이용한 serialization에는 필수적이지는 않지만 그냥 확실히 표시 해 주기 위해서.. AjaxWrapper 을 명시해서 Serializable가 선언된 DTO만 들어올 수 있도록

이경우 MAP을 사용할 수 없지만 -> 이 설계를 잡을 때 명시적인 도메인을 쓰고 map을 쓰지 않는게 원래 목표였으니 잘된건가?

 

Serializable 인터페이스에 대해 알아보기 위해.. 먼저 

Serialization하고 붙어다니는 serialVersionUID 이게 선언되어 있지 않으면 jvm에서 자동으로 생성을 한다고 한다. http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

The stream-unique identifier is a 64-bit hash of the class name, interface class names, methods, and fields. The value must be declared in all versions of a class except the first. It may be declared in the original class but is not required. The value is fixed for all compatible classes. If the SUID is not declared for a class, the value defaults to the hash for that class. The serialVersionUID for dynamic proxy classes and enum types always have the value 0L. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.

영어로 서너번 읽은 것 같은데.. 정확히 이해가 안간다. 첫번째 생성한 클래스.. 변경이 없었다면 0L이 기본으로 셋팅이 될테니 꼭 선언을 할 필요가 없다는것 같다. 클래스에 변경이 있었다면 구버전과 비교를 위해 이 넘버를 명시하는게 필수적이 된다는 거시다.(아마도)

 

Serializable에 대단한 기능이나 의미가 있는 것은 아닌 것 같다. 그냥 JVM에서 제공하는 직렬화를 사용한다고 명시하는 것. JVM에서 기본적으로 제공하는 직렬화/역직렬화 기능을 쓸 때 필수적이고, 내가 예전에 썼던것처럼 그냥 json으로 변환할 오브젝트에다가도 대충 갖다가 써또 되지 않을까 싶다. 그래서 계속 쓰던대로 쓰면 될 것 같다.

 

샘플코드를 작성한다면

Book(v0.1) without uid Book(v0.2) without uid

Book(v0.1) with uid 1 Book(v0.2) with uid 2

Book(v0.1) without uid Book(v0.2) with uid 2

이렇게 해서 비교해보면 될 것 같다

이건 간략예제

//직렬화 FileOutputStream fileOut = new FileOutputStream(“tmp”); ObjectOutput output = new ObjectOutputStream(fileOut); output.writeObject(“object1”); output.writeObject(new Date()); output.flush(); fileOut.close();

//역직렬화 FileInputStream fileIn = new FileInputStream(“tmp”); ObjectInput input = new ObjectInputStream(fileIn); String today = (String)input.readObject(); Date date = (Date)input.readObject(); fileIn.close()