Почему бы не сериализовать абстрактные классы в Java? - PullRequest
7 голосов
/ 15 декабря 2010

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

В чем причина этого?Почему это считается плохим дизайном?

Update1: У меня есть абстрактный класс с некоторыми полями и тремя подклассами.На данный момент я использую следующий подход.

Я сделал все подклассы сериализуемыми с помощью пользовательских методов чтения, записи.В абстрактном классе у меня есть следующие методы.

void writeFields(ObjectOutputStream out)throws IOException { .... }

void readFields(ObjectInputStream in) throws IOException, ClassNotFoundException{ ... }

В пользовательском методе чтения напишите методы в подклассах, которые я вызываю, чтобы (де) сериализовать поля в абстрактном классе.Правильный ли этот подход?Или есть другой лучший подход?

Обновление 2: Я воспользовался советом Тома и сделал свой абстрактный класс сериализуемым.(Я хочу, чтобы все подклассы были сериализуемыми, и у меня есть данные в абстрактном классе). Это отступление, но только для завершения рассказа, который я использую , чтобы изменить окончательные поля, как советовал Джереми Мэнсон.

Ответы [ 4 ]

7 голосов
/ 15 декабря 2010

Я думаю, что причина в том, что если класс Abstract реализует Serializable, нельзя сказать, что подтип НЕ должен быть Serializable.Лучше позволить каждому конкретному типу декларировать себя ...

3 голосов
/ 15 декабря 2010

Я не знаю, что это обязательно плохой дизайн. Сериализация - это проблема реализации (заметьте, Джош Блох со мной не согласен), поэтому не имеет смысла для интерфейсов. Если у абстрактного класса есть состояние, то вы бы хотели сделать его сериализуемым. Если у него нет состояния, на самом деле нет причин делать это.

Давайте рассмотрим пример. java.security.cert.Certificate является абстрактным сериализуемым классом с "type" сериализуемым полем. Если бы он не был сериализуемым, для подкласса не было бы возможности сериализации и установки этого поля. Вы будете вынуждены взломать.

Обратите внимание, что java.io.Serializable это хак. Это не должно было быть интерфейсом. Аннотация (или эволюция языка, например transient) была бы более подходящей.

Как всегда, лучше предпочесть композицию наследованию, а не делать случайный класс сериализуемым.

3 голосов
/ 15 декабря 2010

Давайте займем противоположную позицию. Если бы вы десериализовали объект, какой бы он был?

По определению, абстрактный класс не может быть создан. Если вы можете сериализовать его, это означает, что он также может быть десериализован, и это даст вам экземпляр абстрактного класса. Это противоречит определению абстрактного класса и поэтому не может быть сделано.

0 голосов
/ 27 августа 2014

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

Вот почему.

Например, список не сериализуем, но все основныеРеализация списка есть.(Я знаю, что список - это интерфейс, но абстрактный класс без членов = / = интерфейс)

...