선언부에 "implements Serializable"을 붙이는 순간 이 클래스는 더 이상 싱글턴 클래스가 아니다. readObject 메서드는 새로 생성된 객체를 반환하는데, 이 객체는 클래스가 초기화될 당시에 만들어진 객체와 같은 객체가 아니다.  readResolve를 이용하면 readObject가 만들어낸 객체를 다른 것으로 대체할 수 있다. 역지렬화가 끝나서 만들어진 객체에 대해 이 메서드가 호출되는데, 새로 만들어진 객체 대신, 이 메서드가 반환하는 객체가 사용자에게 반환된다는 것이다. 


 싱글턴 객체처럼, 개체 통제를 위해 readResolve를 활용할 때는, 객체 참조 자료형으로 선언된 모든 객체 필드를 반드시 transient로 선언해야 한다. 이러한 규칙을 지키지 않으면 아래의 오류가 발생할 수 있디/


 하지만 readResolve 메서드가 실행되기 전에 역직렬화된 객체에 대한 참조를 가로 칠 수 있게된다.


 위의 클래스를 작성한 다음 아래의 수작업으로 만들어낸 스트림을 역직렬화하여 두개의 싱글턴 객체를 만들어 내는 코드다.


ENUM클래스를 이용하여 직렬화 가능한 객체 통제 클래스를 구현하면, 선언된 상수 이외의 다른 객체는 존재할 수 없다는 보장이 생긴다. JVM이 해주는 보장이므로 믿을 수 있다.



요약

개체 수와 관련된 불변식을 강제하고 싶을 때는 가능하면 enum을 이용해야 한다. 그렇지 못할 경우, readResolve메서드를 구현해야 하며, 클래스의 모든객체 필드는 기본 자료형으로 하거나 , transient로 선언해야 한다.



+ Recent posts