#76 방어 가능한 readObject 메서드를 작성하자
readObject 메서드는 해당 클래스의 또 다른 public 생성자처럼 생각하고, 생성자처럼 인자의 유효성을 검사하고 필요하다면 매개 변수의 방어 복사본을 만들어야 합니다.
Period 클래스는 직렬화를 지원하는 불변 클래스입니다.
만약 end Date가 start Date보다 더 이르면, IllegalArgumentException을 발생시키고 있습니다.
만약 바이트 스트림을 직접 조작하여 아래와 같이 역직렬화 한다면, 생성자를 통해 검사하던 인자의 유효성 문제를 일으킬 수 있습니다.
인자의 유효성 검사가 없기 때문에, end Date가 start Date보다 더 빠른 결과가 나오는 문제가 발생합니다.
따라서 인자의 유효성을 검사하는 readObject 메서드를 Period 클래스에 추가해야 합니다.
앞서 설명한 Period 클래스는 불변 클래스입니다.
바이트 스트림을 통해 가변적인 Period 인스턴스를 생성할 수 도 있습니다.
이를 통해 Period 내부의 start Date, end Date에 접근해서 불변성에 문제를 일으킬 수 있습니다.
아래 코드를 보면, end Date를 마음대로 변경할 수 있습니다.
방어 복사를 하는 readObject 메서드를 Period 클래스에 추가해야 합니다.
* Date start와 Date end는 readObject 방어 복사를 위해 final을 붙일 수 없습니다.
readObject 메서드를 추가한 후, 실행하면 아래와 같이 불변의 값을 얻을 수 있습니다.
결국 readObject 메서드는 또 다른 형태의 public 생성자라 생각할 수 있습니다.
그리고 바이트 스트림을 조작하면 역직렬화시 예상하지 못한 결과를 얻을 수 있기 때문에, 인자의 유효성을 검사하고 방어 복사본을 생성하는 readOjbect 메서드를 작성해야 합니다.