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


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

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

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

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

9 109

9 ответов:

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

The 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 () обеспечит одноэлементный контракт при сериализации.
Пожалуйста см.

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

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

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