티스토리 뷰

Serializable 구현

  • 클래스 선언에 implements Serializable만 붙이면 된다

Serializable 구현의 문제

  • Serializable을 구현하면 릴리스한 뒤에는 수정하기 어렵다

    • 직렬화 형태도 하나의 공개 API 가 된다
    • 기본 직렬화 형태에서는 private와 package-private 인스턴스 필드들 마저 api로 공개하는 꼴이 된다(캡슐화 깨짐)
    • 직렬화가 클래스 개선을 방해한다
      • UID(명시하지 않으면 런타임시 자동으로 생성해줌)를 생성할때 클래스 멤버들이 고려한다
      • 나중에 수정을 한다면 UID 변한다
  • 버그와 보안 구멍이 생길 위험이 높다

    • 생성자를 사용해서 만드는게 기본인데 기본 메커니즘을 우회하는 객체 생성 기법이다
    • 기본 역직렬화를 사용하면 불변식 깨짐과 허가되지 않은 접근에 쉽게 노출된다
  • 해당 클래스의 신버전을 릴리스할때 테스트할 것이 늘어난다

    • 양방향 직렬화/역직렬화가 모두 성공하고 원래의 객체를 충실히 복제해내는지 반드시 확인해야한다
  • Serializable 구현 여부는 가볍게 결정할 사안이 아니다

    • 객체 전송용으로 쓰일 BigInteger와 Instant 같은 값 클래스와 컬렉션 클래스들은 Serializable을 구현하고 스레드 풀 처럼 동작하는 객체를 표현하는 클래스들은 대부분 Serializable을 구현하지 않았다(이득과 비용을 고려)
  • 상속용으로 설계된 클래스는 대부분 Serializable 을 구현하면 안되며 인터페이스도 대부분 Serializable을 확장해서는 안된다

    • 다만, Serializable을 구현한 클래스만 지원하는 프레임워크를 사용하는 상황이라면 어쩔수 없다.
    • 대표적으로 상속용으로 설계된 클래스 중 Serializable을 구현한 예로 Throwble과 Component가 있다.
    • 클래스의 인스턴스 필드가 직렬화와 확장이 모두 가능하다면 주의할 점이 있다
    • 인스턴스 필드 값 중 불변식을 보장해야 할게 있다면 반드시 하위 클래스에서 finalize 메서드를 재정의 하지 못하게 해야한다(finalizer 재정의하면서 final로 선언)
    • 인스턴스 필드 중 기본값(0, false, null) 으로 초기화되면 위배되는 불변식이 있다면 클래스에 다음의 readObjectNoData메서드를 반드시 추가해야 한다
  • Serializable을 구현하지 않기로 할 때

    • 상속용 클래스의 경우 직렬화를 지원하지 않으면 그 하위 클래스에서 직렬화를 지원하려 할 때 부담이 늘어난다.
    • 역직렬화 하려면 상위 클래스는 매개변수가 없는 생성자를 제공해야 하는데 없는 경우에 직렬화 프록시 패턴을 사용해야 한다
  • 내부 클래스는 직렬화를 구현하지 말아야 한다

    • 내부 클래스에는 바깥 인스턴스의 참조와 유효 범위 안의 지역변수 값들을 저장하기 위해 컴파일러가 생성한 필드들이 자동으로 추가된다. 이 필드들이 클래스 정의에 어떻게 추가 됬는지 정의되지 않았기 때문에 기본 직렬화 형태가 분명하지 않아 이용 불가하다.
    • 단 정적 멤버 클래스는 Serializable을 구현해도 된다

핵심 정리

Serializable은 구현한다고 선언하기는 아주 쉽지만,그것은 눈속임일 뿐이다.안 클래 스의 여러 버전이 상호작용할 일이 없고 서버가 신뢰할 수 없는 데이터에 노출될 가능성 이 없는 등,보호된 환경에서만 쓰일 클래스가 아니라면 Serializable 구현은 아주 신 중하게 이뤄져야 한다.상속할 수 있는 클래스라면 주의사항이 더욱 많아진다

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함