2013-07-09 5 views
1

Я пытаюсь оценить полезность использования объектов Serialized в приложении Java, которое я разрабатываю. Я пытаюсь определить, имеет ли значение смысл для реализации сериализации Object, или если я должен настраивать транспорт. Вот мой сценарий:Сериализация объектов Java

  • Объекты будут транспортироваться через TCP из одного приложения в другое.
  • Сериализованный объект будет экземпляром класса, хранящегося в общей библиотеке.

образца Класс:

public class Room implements Serializable { 
    // Instance Variables 
    private Room roomWithinRoom; 
    // ... 
} 

Так что мой вопрос заключается в том, что, так как у меня будет несколько переменных экземпляра, которые ссылаются обратно в класс номер, можно использовать Java сериализацию для выполнения передачи объектов в номере? Если я смогу выполнить это, будут ли указатели сохранены?

Пример:

Room mainRoom = new Room(); 
Room closet = new Room(); 
mainRoom.addRoom(closet); 

Если я посылаю над объектом «mainRoom,» будет также сериализовать и отправить «шкаф» экземпляр

Спасибо (сохранение переменной экземпляра roomWithinRoom в mainRoom?) пучок, все!

ответ

1

Да, сериализация Java делает это очень хорошо. Может быть, слишком хорошо. Мне повезло с файлами. С TCP не забудьте позвонить по номеру reset после каждой записи. Java отправит целый сетевой граф за один раз - ваш объект, все ссылки на объекты, все, что они ссылаются, и так далее. Один writeObject может отправлять гигабайты данных. Но без сброса, если следующий объект, который вы пишете, был включен в первый граф, все, что будет проходить, будет ссылкой на ранее отправленный объект. Любые обновленные данные будут проигнорированы. (Я упоминал, что вы должны позвонить по номеру reset после каждого writeObject?)

Я бы предложил использовать интерфейс Externalizable. Это дает вам немного больше контроля над тем, что написано. (На самом деле это делается на основе класса, поэтому некоторые классы могут быть Serializable и некоторые Externalizable без проблем.) Это означает, что вы можете писать в том же формате, даже если класс немного изменится. Он позволяет пропустить данные, которые вам не нужны, и иногда передавать тривиальные объекты в качестве примитивов данных. Я также использую номера версий, поэтому более новые версии класса могут читать вещи, написанные более старыми версиями. (Это немного важнее при написании файлов, чем в TCP.) Предупреждение: при чтении класса имейте в виду, что ссылка на объект, которую вы только что прочитали, может не ссылаться на любые данные (т. Е. Объект ссылки еще не читается, вы смотрите на унифицированную память, где данные объекта будет идите.).

Возможно, вы немного потрудитесь, но это действительно хорошо работает, как только вы это поймете.

+0

Я не вижу, что TCP связано с вызовом reset(), и поскольку он хочет сохранить ссылки, я не вижу, почему вы рекомендуете reset() вообще. Для преодоления изменений класса вам не требуется Externalizable: в Спецификации сериализации объектов есть большая глава, которая определяет совместимость различных изменений, которая намного более обширна, чем кажется большинству людей, даже если они ее прочитали. – EJP

+0

@EJP: Вы хотите, чтобы ссылки сохранялись в одной записи. Вы отправляете один объект и включаете остальную часть своего графа объектов. Это то, что вы хотите. Обновите объекты в графике и отправьте их один раз, и ObjectOutput отметит, что он уже отправил их и ничего не делает, кроме как отправить сообщение, чтобы повторить предыдущий вывод. Никакие новые данные не будут переданы. – RalphChapin

+0

@EJP: Другая проблема заключается в том, что ObjectOutput и Input никогда не забудут объект. Если вы отправляете кучу несвязанных объектов, каждый из них пройдет, но все они будут помнить. Если вы подключены в течение нескольких рабочих часов, это может использовать много памяти на обоих концах. (И если вы повторяете объект, читатель получает первый отправленный, последние данные копии не пройдут.) – RalphChapin

0

Ссылки будут сохранены в графе объектов, и любые вложенные объекты будут также правильно сериализованы, если они реализуют сериализуемый интерфейс и не будут отмечены переходными процессами.

Я советую использовать встроенную сериализацию Java, поскольку она более подробно, чем другие бинарные протоколы. Также всегда существует потенциальный, что процедуры сериализации/десериализации могут меняться между временем выполнения.

По этим причинам я предлагаю ProtoBufs. ProtoBuf является небольшим, быстрым и даже может использоваться для быстрого создания процедур сериализации/десериализации на языках, отличных от Java, поскольку вы найдете компилятор protobuf для этого языка.

Смежные вопросы