Сериализация несериализуемых объектов из не редактируемых классов API [duplicate]

В веб-приложении каждая задача выполняется в виде запроса и ответа.

Программирование на стороне клиента - это HTML-код с Java-скриптом и его фреймворками, библиотеки выполняются в Internet Explorer, Mozilla, Chrome-браузерах. В сценарии Java-сценария серверные сервлеты программирования выполняются в Tomcat, web-логике, j боссе, WebSphere severs

52
задан Burkhard 18 September 2008 в 19:15
поделиться

10 ответов

Как заметил еще один, глава 11 Эффективной Java Джоша Блоха является незаменимым ресурсом в Java Serialization.

Пара вопросов, относящихся к этой главе, относящейся к вашему вопросу:

  • , предполагая, что вы хотите сериализовать состояние несериализуемого поля в MyClass2, это поле должно быть доступно для MyClass напрямую или через геттеры и сеттеры. MyClass должен будет реализовать пользовательскую сериализацию, предоставляя методы readObject и writeObject.
  • класс несериализуемого поля должен иметь API, позволяющий получать его состояние (для записи в поток объектов), а затем создавать экземпляр нового экземпляра с этим состоянием (при последующем чтении из потока объектов.)
  • за элемент 74 Эффективной Java, MyClass2 должен иметь конструктор no-arg, доступный для MyClass, иначе это невозможно для MyClass для расширения MyClass2 и реализации Serializable.

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


class MyClass extends MyClass2 implements Serializable{

  public MyClass(int quantity) {
    setNonSerializableProperty(new NonSerializableClass(quantity));
  }

  private void writeObject(java.io.ObjectOutputStream out)
  throws IOException{
    // note, here we don't need out.defaultWriteObject(); because
    // MyClass has no other state to serialize
    out.writeInt(super.getNonSerializableProperty().getQuantity());
  }

  private void readObject(java.io.ObjectInputStream in)
  throws IOException {
    // note, here we don't need in.defaultReadObject();
    // because MyClass has no other state to deserialize
    super.setNonSerializableProperty(new NonSerializableClass(in.readInt()));
  }
}

/* this class must have no-arg constructor accessible to MyClass */
class MyClass2 {

  /* this property must be gettable/settable by MyClass.  It cannot be final, therefore. */
  private NonSerializableClass nonSerializableProperty;

  public void setNonSerializableProperty(NonSerializableClass nonSerializableProperty) {
    this.nonSerializableProperty = nonSerializableProperty;
  }

  public NonSerializableClass getNonSerializableProperty() {
    return nonSerializableProperty;
  }
}

class NonSerializableClass{

  private final int quantity;

  public NonSerializableClass(int quantity){
    this.quantity = quantity;
  }

  public int getQuantity() {
    return quantity;
  }
}
49
ответ дан Scott Bale 24 August 2018 в 00:22
поделиться
  • 1
    Все, что я надеялся на какую-то аннотацию, например @NonSerialization: - / – Oliver Dixon 17 October 2015 в 09:36

XStream - отличная библиотека для быстрой сериализации Java для XML для любого объекта независимо от того, является ли она Serializable или нет. Даже если целевой формат XML вам не подходит, вы можете использовать исходный код, чтобы узнать, как это сделать.

3
ответ дан Boris Terzic 24 August 2018 в 00:22
поделиться
  • 1
    привет, не могли бы вы объяснить, как использовать XStream с несериализуемым объектом? – SWAppDev 26 November 2015 в 14:33
  • 2
    Документация очень понятна, учебник начинается с классов, которые не реализуют Serializable, и показывает вам, как их сериализовать: x-stream.github.io/tutorial.html – Boris Terzic 27 November 2015 в 16:00

Выпущено несколько возможностей и я возобновил их здесь:

  • Реализовать writeObject () и readObject (), поскольку sk предложил
  • объявить и он не будет сериализован, как указано в hank
  • , использовать XStream, как указано в boris-terzic
  • используйте Serial Proxy, как указано в tom-hawtin-tackline
4
ответ дан Community 24 August 2018 в 00:22
поделиться

Вы можете начать с поиска ключевого слова transient , которое помечает поля как не относящиеся к постоянному состоянию объекта.

4
ответ дан Hank 24 August 2018 в 00:22
поделиться

Вам нужно будет реализовать writeObject() и readObject() и выполнить ручную сериализацию / десериализацию этих полей. Подробнее см. На странице javadoc для java.io.Serializable. Эффективный Java Josh Bloch также имеет некоторые хорошие главы по внедрению надежной и безопасной сериализации.

6
ответ дан jediz 24 August 2018 в 00:22
поделиться

MyClass2 - это просто интерфейс, поэтому он не имеет свойств, а только методов. Если у вас есть переменные экземпляра, которые сами по себе не являются сериализуемыми, единственный способ, которым я знаю, чтобы обойти это, - объявить эти поля переходными.

ex:

private transient Foo foo;

Когда вы объявляете переходный период поля, он будет игнорироваться во время процесса сериализации и десериализации. Имейте в виду, что при десериализации объекта с переходным полем значение поля всегда будет по умолчанию (обычно null.)

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

34
ответ дан Mike Deck 24 August 2018 в 00:22
поделиться

Если возможно, несериализуемые части могут быть установлены как переходные

private transient SomeClass myClz;

В противном случае вы можете использовать Kryo . Kryo - это быстрая и эффективная структура сериализации графа объектов для Java (например, JAVA-сериализация java.awt.Color требует 170 байт, Kryo всего 4 байта), которая может сериализовать и несериализуемые объекты. Kryo также может выполнять автоматическое глубокое и мелкое копирование / клонирование. Это прямое копирование из объекта в объект, а не object->bytes->object.

Вот пример использования kryo

Kryo kryo = new Kryo();
// #### Store to disk...
Output output = new Output(new FileOutputStream("file.bin"));
SomeClass someObject = ...
kryo.writeObject(output, someObject);
output.close();
// ### Restore from disk...
Input input = new Input(new FileInputStream("file.bin"));
SomeClass someObject = kryo.readObject(input, SomeClass.class);
input.close();

Сериализованные объекты также могут быть сжаты путем регистрации точного сериализатора:

kryo.register(SomeObject.class, new DeflateCompressor(new FieldSerializer(kryo, SomeObject.class)));
15
ответ дан MSX 24 August 2018 в 00:22
поделиться

Зависит от того, почему этот член MyClass2 не является сериализуемым.

Если есть какая-то веская причина, почему MyClass2 не может быть представлен в сериализованной форме, то, вероятно, по той же причине применимы к MyClass, поскольку это подкласс.

Возможно, можно написать пользовательскую сериализованную форму для MyClass, реализовав readObject и writeObject таким образом, чтобы состояние данных экземпляра MyClass2 в MyClass можно было соответствующим образом воссоздать из сериализованного данные. Это был бы путь, если бы API MyClass2 был исправлен, и вы не можете добавить Serializable.

Но сначала вы должны выяснить, почему MyClass2 не является сериализуемым и, возможно, его изменить.

5
ответ дан Steve Jessop 24 August 2018 в 00:22
поделиться

Полезный подход для сериализации экземпляров несериализуемых классов (или, по крайней мере, подклассов) известен Serial Proxy. По сути, вы выполняете writeReplace, чтобы возвращать экземпляр совершенно другого сериализуемого класса, который реализует readResolve для возврата копии исходного объекта. Я написал пример сериализации java.awt.BasicStroke в Usenet

2
ответ дан Tom Hawtin - tackline 24 August 2018 в 00:22
поделиться

Если вы можете изменить MyClass2, самый простой способ обратиться к этому - объявить переходный ресурс.

11
ответ дан ykaganovich 24 August 2018 в 00:22
поделиться
  • 1
    Это не отвечает на вопрос - вопрос заключается в том, что MyClass2 содержит свойство, которое не является сериализуемым, и в идеале MyClass2 не следует изменять. – Scott Bale 7 September 2012 в 19:20
  • 2
    Вы правы, я не очень внимательно прочитал этот вопрос, когда я ответил на него. Я изменил ответ. – ykaganovich 7 September 2012 в 19:46
Другие вопросы по тегам:

Похожие вопросы: