안녕하세요. 이 글에서는 Serializable에 대해서 상세히 다루지 않습니다. 다만, java에서 transient 키워드에 대해서 간단하게만 다뤄보고자 합니다.

 


 transient가 무엇을 하는 지 알아보기 위해 Serializable을 implements 했어요. 굵게 쳐져 있는 Warning. 신뢰되지 않는 데이터를 역직렬화를 시키지 말아달라는 부분이 있긴 하지만, 여기에서는 다룰 주제가 아닙니다. 직렬화? 뭘 어떻게 한다는 것일까요? data class를 직렬화 시켜서 파일로 떨궈보겠습니다.

 

 

 그랬더니 byte 형태로 표현이 되었어요. AC ED 00 05 ... 00 02

 

 

 data의 내용을 조금 조작해서 직렬화를 시켜 봤더니 요래 나왔네요. AC ED 00 ... 01. 우리가 객체를 누군가와 통신할 필요가 있을 때, 객체 자체를 넘길 수는 없을 겁니다. 적절한 변환을 거쳐서 보낼 수 있는 형태로 만들 건데, byte stream 같은 것들도 이에 속할 겁니다.

 

 저 데이터를 객체로 변환하는 작업을 역직렬화라고 하는데요. Serializable 에서 warning이 뜬 부분은 이 부분입니다. 신뢰할 수 없는 데이터일 때 함부로 역직렬화를 하면 큰일난다.

 


 transient가 뭘 하는 친구인지 알아보기 위해, data 클래스를 하나 준비해 보겠습니다. field x와 y가 있습니다.

 

 이 클래스는 setter, getter, toString, equals, hashCode 등이 정의되어 있습니다. Main 클래스를 보겠습니다.

 

 

 먼저, 필드 x의 값이 1이고, 필드 y의 값이 2인 data 객체를 생성합니다. 다음에, ObjectOutputStream으로 obj.out에 data 객체를 직렬화한 결과를 쓰게 됩니다.

 

 

 다음에, obj.out으로부터 역직렬화 해서 data 객체를 얻어옵니다.

 

 실행 결과는 위와 같습니다.

 


 이제 y 앞에 transient를 붙여 보겠습니다. 그런 다음에 똑같이 필드 x값이 1이고, y 값이 2인 data 객체 d를 직렬화 한 후에, 다시 역직렬화 해 보겠습니다.

 

 

 그러면 아까와는 다르게 y의 값이 0임을 알 수 있는데요. 2가 나올 것을 기대했는데 그러지 않았습니다. 이는 직렬화 대상에서 제외했음을 의미합니다. 이 부분은 어디서 볼 수 있을까요? ObjectOutputStream의 writeObject 메서드를 쭉 타고 정보를 쓸 필드들을 언제 얻어오는지에 집중해서 tracking을 해 보면, ObjectStreamClass의 getDefaultSerialFields를 만나게 됩니다.

 

 

 getDefaultSerialFields 부분을 보면 mask가 보이네요. 그리고 cl도 있는데요. 잘은 모르겠지만, 1820번째 줄에 붙어있는 메소드 이름을 보았을 때, 클래스의 메타 데이터에 대한 정보를 얻어오는 무언가라고 생각할 수 있어요.

 

 

 이 필드들 중에서 STATIC이나 TRANSIENT가 아닌 경우에만 list에 add를 해서 리턴하게끔 되어 있어요. 아. 그러면 중간에 필드들의 메타 데이터를 가지고 직렬화할 대상을 필터링 걸게 되고, 그 다음에 Object의 정보를 바이트 형태로 변환한다는 것 정도만 알 수 있겠네요.