[java] 자바 직렬화 : readObject () vs. readResolve ()

Effective Java 및 기타 소스 책 은 직렬화 가능 Java 클래스로 작업 할 때 readObject () 메소드를 사용하는 방법과시기에 대한 좋은 설명을 제공합니다. 반면에 readResolve () 메소드는 약간의 수수께끼로 남아 있습니다. 기본적으로 내가 찾은 모든 문서는 둘 중 하나만 언급하거나 둘 다 개별적으로 언급했습니다.

답변되지 않은 질문은 다음과 같습니다.

  • 두 방법의 차이점은 무엇입니까?
  • 언제 어떤 방법을 구현해야합니까?
  • 특히 무엇을 반환한다는 점에서 readResolve ()를 어떻게 사용해야합니까?

이 문제에 대해 약간의 지식을 밝힐 수 있기를 바랍니다.



답변

readResolve스트림에서 읽은 객체 를 바꾸는 데 사용됩니다 . 제가 지금까지 본 유일한 용도는 싱글 톤을 적용하는 것입니다. 객체를 읽으면 싱글 톤 인스턴스로 교체하십시오. 이렇게하면 아무도 싱글 톤을 직렬화하고 역 직렬화하여 다른 인스턴스를 만들 수 없습니다.


답변

항목 90, 유효 Java, 3 차 Ed readResolvewriteReplace직렬 프록시-주요 용도. 예제는 기본 직렬화를 사용하여 필드를 읽고 쓰므로 쓰기 readObjectwriteObject메소드를 작성하지 않습니다 .

readResolvereadObject반환 된 후 호출됩니다 (반대로 writeReplacewriteObject다른 객체에서 호출 됨). 메소드가 돌려주는 this객체는, 유저에게 돌려 주어진 객체 ObjectInputStream.readObject와, 스트림 내의 객체에 대한 추가의 참조를 치환 합니다 . 모두 readResolvewriteReplace동일하거나 서로 다른 유형의 객체를 반환 할 수 있습니다. 동일한 유형을 반환하면 필드가 있어야 final하고 이전 버전과의 호환성이 필요하거나 값을 복사 및 / 또는 검증 해야하는 경우에 유용 합니다.

readResolve싱글 톤 속성을 사용 하지 않습니다.


답변

readResolve를 사용하여 readObject 메소드를 통해 직렬화 된 데이터를 변경할 수 있습니다. 예를 들어 xstream API는이 기능을 사용하여 직렬화 해제 할 XML에없는 일부 속성을 초기화합니다.

http://x-stream.github.io/faq.html#Serialization


답변

readResolve는 기존 객체를 반환해야하는 경우를위한 것입니다. 예를 들어 병합해야 할 중복 입력을 확인 중이거나 (예 : 일관된 분산 시스템에서) 인식하기 전에 도착할 수있는 업데이트이므로 이전 버전


답변

readObject ()는 ObjectInputStream 클래스 의 기존 메소드 입니다. deserialization시 객체를 읽는 동안 readObject 메소드는 readResolve 메소드를 사용하여 deserialize되는 클래스 객체를 내부적으로 확인합니다. 예.

따라서 readResolve 메소드를 작성하려는 의도는 직렬화 / 역 직렬화를 통해 다른 인스턴스를 얻을 수없는 순수한 싱글 톤 디자인 패턴을 달성하는 것이 좋습니다.


답변

readResolve ()는 직렬화 중에 싱글 톤 계약을 보장합니다.
제발 참조


답변

직렬화를 사용하여 객체를 파일로 저장할 수 있도록 변환하면 readResolve () 메소드를 트리거 할 수 있습니다. 이 메소드는 개인용이며 직렬화 해제 중에 오브젝트를 검색하는 동일한 클래스에 유지됩니다. 역 직렬화 후에 반환되는 객체가 직렬화 된 것과 동일하게됩니다. 그건,instanceSer.hashCode() == instanceDeSer.hashCode()

readResolve () 메소드는 정적 메소드가 아닙니다. in.readObject()역 직렬화하는 동안 호출 된 후에 는 반환 된 객체가 다음과 같이 직렬화 된 객체와 동일한 지 확인합니다.out.writeObject(instanceSer)

..
    ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file1.ser"));
    out.writeObject(instanceSer);
    out.close();

이런 식으로, 그것은 또한 도움이 으로 동일한 인스턴스가 반환 될 때마다 싱글 톤 디자인 패턴 구현에 .

public static ABCSingleton getInstance(){
    return ABCSingleton.instance; //instance is static 
}