Serializable 구현과 관련된 가장 큰 문제는 일단 클래스를 릴리즈하고 나면 클래스 구현을 유연하게 바꾸기 어려워진다는 것이다. Serializable을 구현하면 그 클래스의 바이트 스트림 인코딩(직렬화방식)도 공개 API의 일부가 되어 버린다. 사용자 정의 직렬화형식을 설계하지 않고 기본 형식을 그대로 이용할 경우, 직렬화 형식은 영원히 클래스의 원래 내부 표현방식에 종속된다. 다시 말해, 기본 직렬화 형식을 받아 들이면 그 클래스의  private와 pacakage-private 객체 필드도 공개 API가 된다는 것이다. 정보은닉을 위해 필드의 접근 권한은 최소화해야 한다는 원칙은 효력을 잃게 된다.


Serialiable을 구현하는 생기는 두 번째 문제는, 버그나 보안 취약점이 발생할 가능성이 높다는 것이다. 보통 객체는 생성자를 통해 생성한다. 직렬화는 언어 외적인 객체 생성 메커니즘이다. 역직렬화는 생성자와 동일한 이슈를 갖고 있는 "숨은 생성자"다. 역직렬화 과정에 관계된 생성자가 명시적으로 존재하지 않기 때문에 생성자가 만족하는 모든 불변식을 보장해야 하는데, 일반적으로 이러한 과정을 놓치는 경우가 많다. 


Serializable을 구현하는 생기는 세 번째 문제는, 새 버전 클래스를 내놓기 위한 테스트 부담이 늘어난다. 직렬화 가능 클래스를 수정할 때는, 새 릴리즈에서 만들고 직렬화한 객체를 예전 릴리즈에서 역직렬화할 수 있는지, 그 역도 가능한지 검사하는 것이 중요하다. 또한 객체 원래의 기능도 문제가 없는지 테스트해봐야 한다. 


계승을 염두에 두고 설계하는 클래스는 Serializable을 구현하지 않는 것이 바람직하다. 또한 인터페이스는 가급적 Serializable을 계승하지 말아야 한다.


내부 클래스는 Serializable 을 구현하는 안된다. 내부 클래스에는 바깥 객체에 대한 참조를 보관하고 바깥 유효범위의 지연 변수 값을 보관하기 위해 컴파일러가 자동으로 생성하는 인위생성 필드가 있다. 익명클래스나 지역 클래스 이름과 마찬가지로, 언어 명세서에는 이런 필드가 클래스 정의에 어떻게 들어 맞는지 나와있지 않다. 따라서 내부 클래스의 기본 직렬화 형식은 정의될 수 없다. 인위생성 필드 때문에 ..? 



+ Recent posts