[아이템 86] Serializable을 구현할지는 신중히 결정하라.
Serializable을 구현하면 릴리스 한 뒤에는 수정하기 어렵습니다. 직렬화 당시 내부 구현 방식에 묶이고, 캡슐화가 깨지는 위험이 있습니다. 직렬화된 클래스는 고유 식별 번호를 부여받는데, serialVersionUID를 명시하지 않으면 런타임에 SHA-1을 적용하여 자동으로 클래스 안에 생성해 넣는데, 클래스의 이름, 멤버 등이 포함됩니다. 그래서 나중에 이들 중 하나를 수정한다면 UID 값도 변하여 호환성이 깨져버립니다.
그 다음 문제는 역직렬화는 숨은 생성자 입니다. 기본 역직렬화를 사용하면 불변식이 깨지고 허가되지 은 접근에 쉽게 노출됩니다. 세 번째 문제는 해당 클래스의 신버전을 릴리즈 할 때마다 직렬화 호환성을 검사해야하기 때문에 테스트해야 할 양이 직렬화 가능 클래스의 수와 릴리스 횟수에 비례하여 증가합니다. 그래서 Serializable 구현 여부는 신중하게 결정해야합니다. 단 객체를 전송 / 저장할 때 자바 직렬화를 이용하는 프레임워크용으로 만든 클래스라면 선택의 여지가 없습니다. 상속용으로 설계된 클래스나 인터페이스는 대부분 `Serializable`을 구현하면 안 됩니다. 그렇지 않으면 이 클래스를 확장할 때마다 커다란 부담감을 안겨주게됩니다. 예외적으로 `Throwable`은 서버가 RMI를 통해 클라이언트로 예외를 보내기 위해 Serializable을 구현했습니다. 작성하는 클래스의 인스턴스 필드가 직렬화와 확장이 가능하다면 주의해야 할 것이 있습니다. finalize 메서드를 재정의하지 못하게 해야합니다. 그렇게 하지 않으면 finalizer 공격을 당할 수 있습니다. 마지막으로 인스턴스 필드 중 기본값으로 초기화하면 안 된다면 다음의 readObjectNoData 메서드를 반드시 추가해야합니다.
|
|