Частичная (де) сериализация Java-объектов
Допустим, у нас есть 3 класса:
class foo { // not a singleton
String s;
}
class bar {
foo f;
int i;
}
class baz {
foo sameF;
}
Теперь мы создаем экземпляры
foo onlyFoo = new foo("the only one");
bar theBar = new bar(onlyFoo, 123);
baz theBaz = new baz(onlyFoo);
После этого мы хотим сохранить их serilazed в файле. Если мы десериализуем theBaz, модифицируем onlyFoo и снова десериализуем theBaz в файл, theBar по-прежнему содержит исходный onlyFoo, так что есть две разные версии onlyFoo.
Вместо этого я хочу, чтобы я сохранял theBaz и theBar без onlyFoo, сохранял эти три объекта отдельно, и как только кто-то десериализует Баз, я тоже хочу дать ему только Foo. Если он снова десериализует измененный onlyFoo, то у баз и theBar будет изменен один и тот же модифицированный onlyFoo, поэтому, если кто-то запрашивает объект (например, theBar), он получает полностью сериализованный объект со всеми ссылочными объектами (onlyFoo), как при обычном процессе сериализации,
Я знаю, что мне нужно хранить объекты и хранить ссылки вручную и отдельно, потому что сериализация по умолчанию не может решить эту проблему. Чего я не знаю, так это как частично сериализовать / десериализовать объекты Java? Мне нужно отделить примитивы и их обертки от "высших" объектов и хранить их отдельно.
Обновить
- Я не могу изменить классы.
- Я не знаю всех классов. Он должен работать со всеми сериализуемыми объектами, о которых я, возможно, никогда не слышал (они могут быть или не быть окончательными)
3 ответа
Если вы хотите больше контроля, вы можете перезаписать writeObject() и readObject() и сериализовать себя.
class bar {
...
private void writeObject(ObjectOutputStream stream) throws IOException {
// let version 1, later when you need to have versioning.
stream.writeInt(version);
stream.writeInt(i);
// leave out
// stream.writeObject(foo);
}
}
// read object the analog, see
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html
Пометить ссылки, которые вы не хотите сериализовать, с помощью временного ключевого слова.
Ты можешь сделать foo
transient
как ниже.
class bar {
transient foo f;
int i;
}