Сериализация Java: readObject () против readResolve()

книги Эффективная Java и другие источники предоставляют довольно хорошее объяснение того, как и когда использовать метод readObject() при работе с сериализуемыми классами Java. Метод readResolve (), с другой стороны, остается немного загадочным. В основном все документы, которые я нашел, либо упоминают только один из двух, либо упоминают оба только индивидуально.

вопросы, которые остаются без ответа являются:

  • в чем разница между двумя методы?
  • когда должен быть реализован какой метод?
  • как следует использовать readResolve (), особенно с точки зрения возврата чего?

надеюсь, вы сможете пролить свет на этот вопрос.

9 ответов


readResolve используется замена объект считывается из потока. Единственное использование, которое я когда-либо видел для этого, - это применение синглетов; когда объект читается, замените его экземпляром singleton. Это гарантирует, что никто не сможет создать другой экземпляр путем сериализации и десериализации синглтона.


на readResolve метод вызывается, когда ObjectInputStream прочитал объект из потока и готовится вернуть его вызывающему. ObjectInputStream проверяет, определяет ли класс объекта readResolve метод. Если метод определен, то readResolve метод вызывается, чтобы позволить объекту в потоке назначить возвращаемый объект. Возвращаемый объект должен иметь тип, совместимый со всеми видами использования. Если он не совместим, a ClassCastException будет брошен, когда несоответствие типа обнаруженный.


readResolve вызывается после readObject вернулся (и наоборот writeReplace вызывается перед writeObject и, вероятно, на другой объект). Объект возвращает метод заменяет this объект возвращается пользователю ObjectInputStream.readObject и любые дальнейшие обратные ссылки на объект в потоке. Он в основном используется для последовательных прокси (см. эффективный Java, 2nd Ed, IIRC).


readResolve можно использовать для изменения данных, сериализованных с помощью метода readObject. Например, xStream API использует эту функцию для инициализации некоторых атрибутов, которые не были десериализованы в XML.

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


readResolve предназначен для того, когда вам может потребоваться вернуть существующий объект, например, потому, что вы проверяете дубликаты входных данных, которые должны быть объединены, или (например, в в конечном итоге согласованных распределенных системах), потому что это обновление, которое может прибыть до того, как вы узнаете о любых старых версиях.


readResolve () обеспечит одноэлементный контракт во время сериализации.
Пожалуйста!--2-->refer


когда сериализация используется для преобразования объекта, чтобы его можно было сохранить в файле, мы можем вызвать метод 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 
}

readObject () - это существующий метод в ObjectInputStream класса.при чтении объекта во время десериализации метод readObject внутренне проверяет, является ли объект класса, который десериализуется с помощью метода readResolve или нет, если метод readResolve существует, то он вызовет метод readResolve и вернет тот же экземпляр.

таким образом, интенсивный метод readResolve - хорошая практика для достижения чистого одноэлементного Шаблона дизайна, где никто не может получить другой экземпляр путем сериализации/десериализации.


метод readResolve

для Сериализуемых и Экстернализуемых классов метод readResolve позволяет классу заменить / разрешить объект, считанный из потока, прежде чем он будет возвращен вызывающему объекту. Реализуя метод readResolve, класс может напрямую управлять типами и экземплярами собственных десериализуемых экземпляров. Метод определяется следующим образом:

любой доступ-модификатор объекта readResolve() бросает ObjectStreamException;

на readResolve метод вызывается, когда ObjectInputStream прочитал объект из потока и готовится вернуть его вызывающему. ObjectInputStream проверяет, определяет ли класс объекта метод readResolve. Если метод определен, метод readResolve вызывается, чтобы позволить объекту в потоке назначить возвращаемый объект. Возвращаемый объект должен иметь тип, который совместим со всеми видами использования. Если он не совместим, a ClassCastException будет брошен, когда будет обнаружено несоответствие типа.

например, a символ может быть создан класс, для которого в виртуальной машине существует только один экземпляр каждой привязки символов. The readResolve метод будет реализован, чтобы определить, был ли этот символ уже определен и заменить существующий эквивалентный объект символа для поддержания ограничение идентификации. Таким образом, уникальность символьных объектов может поддерживаться во всей сериализации.