Effective Java 3/E - (12) 직렬화

신복호·2020년 12월 6일
0

Effactive JAVA 3/E

목록 보기
11/12
post-thumbnail

12장 직렬화

아이템 85. 자바 직렬화의 대안을 찾으라 : JSON, protocolBuf

  • 직렬화의 근본적인 문제는 공격범위가 너무 넓고 지속적으로 더 넓어져 방어하기 어렵다는 점이다.

  • 직렬화 위험을 회피하는 가장 좋은 방법은 아무것도 역직렬화하지 않는것이다.

  • 특히 신뢰할 수 없는 데이터는 절대로 역직렬화를 하지 말아야 한다.

아이템 86. Serializable을 구현할지는 신중하게 결정하라

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

  • 버그와 보안 구멍이 생길 위험성이 높아 진다. (아이템 85)

  • 해당 클래스의 신버전을 릴리스 핳때 테스트 할 것이 늘어난다는 점이다.

  • Serializable 구현 여부는 가볍게 결정할 사안이 아니다 (단. 객체를 전송하거나 저장할때 자바 직렬화를 이용하는 프레임워크용으로 만든 클라스라면 선택의 여지가 없다.)

  • 상속용으로 설계된 클래스 (아이템 19)는 대부분 Serializable을 구현하면 안되며, 이넡페이스도 대부분 Serializable을 확장해선 안된다.

  • 내부 클래스 (아아템 24)는 직렬화를 구현하면 안된다.

아이템 87. 커스텀 직렬화 형태를 고려해봐라

  • 먼저 고민해보고 괜찮다고 판단될 떄만 기본 직렬화 형태를 사용하라.

  • 객체의 물리적 표현과 논리적 내용이 같다면 기본 직렬화 형태라도 무방하다.

  • 기본 직렬화 형태가 적합하다고 결정 했ㄷ더라도 불변식 보장과 보안을 위해 readObject 메소드를 제공해야 할 때가 많다.

  • 객체의 물리적 표현과 논리적 표현의 차이가 클때 기본 직렬화 형태를 사용하면 크게 네 가지 면에서 문제가 생긴다.

    • 공개 API가 현재의 내부 표현 방식에 영구적으로 묶인다.

    • 너무나 많은 공간을 차지 할수 있다.

    • 시간이 너무 많이 걸릴수 있다.

    • 스택 오버플로우를 일으킬수 있다.

  • 해당 객체가 논리적 상태와 무관한 필드라고 확신할 때만 transient 한정자를 생략해야 한다.

  • 객체의 전체 상태를 읽는 메소드에 적용해야 하는 동기화 메커니즘을 직렬화에도 적용해야 한다.

  • 어떤 직렬화 형태를 택하든 직려로하 가능 클래스 모두에 직렬버전 UID를 명시적으로 사용하자.

  • 구버전으로 직렬화된 인스턴스들과의 호환성을 끊을려는 경우를 제외하고 직렬버전 UID를 절대 수정하지 말아야 한다.

아이템 88. readObject 메서드는 방어적으로 작성하라

  • readObjet 메소드를 작성할 떄에는 언제나 public 생성자를 작성하는 자세로 임해야 한다.

  • readObject는 어떤 바이트 스트림이 넘어와더라도 유효한 인스턴스를 만들어 내야 한다.

    • private이어야 하는 객체 참조 필드는 각 필드가 가리키는 객체를 방어적으로 복사해라. 불변 클래스 내의 가변 요소가 여기 속한다.

    • 모든 불변식을 검사하여 어긋나는 게 발견되면 InvalidObjectException을 던진다. 방어적 복사 다음에는 반드시 불변식 검사가 뒤따라야 한다.

    • 역직렬화 후 객체 그래프 전체의 유효성을 검사해야한다면 ObjectInputValidation 인터페이스를 사용하라

    • 직접적이던 간접적이던, 재정의 할수 있는 메소드는 호출 하지 말자

아이템 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 enum을 사용하자

  • 불변식을 지키기 위해 인스턴스를 통제해야 한다면 가능한 한 열거 타입을 사용하는 것이 좋다.

  • 여의치 않는 상황에서 직렬화와 인스턴스 통제가 모두 필요하다면 readResolve메소드를 넣어야 하고 그 클래스에서 모든 참조타입 인스턴스 필드를 transient으로 선언해야 한다.

아이템 90. 직렬화된 인스턴스 대신에 직렬화 프록시를 사용하자.

  • 제 3자가 확장할 수 없는 클래스라면 가능한 직렬화 프록시 패턴을 사용하자. 이 패턴이 아마도 중요한 불변식을 안정적으로 직렬화 해주는 가장 쉬운 방법이다.
profile
한참 열정이 가득한 백엔드 개발자입니다.

0개의 댓글