Why not serialize abstract classes in Java?

2019-03-20 01:40发布

问题:

I have read that generally abstract classes should not be made Serializable in Java. The subclasses should be serializable (with custom read, write methods if required, for eg. when abstract classes have fields).

What is the reason behind this? Why is it considered bad design?

Update1: I have an abstract class with some fields and three subclasses. As of now, I am using the following approach.

I have made all the subclasses serializable with custom read, write methods. In the abstract class I have the following methods.

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

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

In the custom read, write methods in the subclasses I call these methods to (de) serialize the fields in the abstract class. Is this approach correct? Or is there a different better approach?

Update 2: I took Tom's advice and made my abstract class Serializable. (I want all subclasses to be Serializable and I have data in the abstract class) This is an aside, but just to complete the story I am using reflection to change final fields as advised by Jeremy Manson.

回答1:

I don't know that it is necessarily bad design. Serialisation is effectively an implementation issue (note, Josh Bloch disagrees with me), so doesn't make sense for interfaces. If the abstract class has state, then you would want to make it serialisable. If it doesn't have state, there isn't really any reason to make it so.

Let's take an example. java.security.cert.Certificate is an abstract serialisable class, with a "type" serialisable field. If it wasn't serialisable it would not be possible for a subclass to be serialisable and set that field. You would be forced in to a hack.

Note that java.io.Serializable is a hack. It shouldn't have been an interface. An annotation (or language evolution like transient) would have been more appropriate.

As always, it's best to prefer composition to inheritance and not to make random class serialisable.



回答2:

I think the reason is that if an Abstract class implements Serializable, there is no way to say that a sub type should NOT be Serializable. Better to let each concrete type declare for itself...



回答3:

Let's take the oposite position. If you were to De-Serialize the object, what would be its type?

By definition, an abstract class can't be instantiated. If you can serialize it, that implies that it can also be deserialized and that would get you an instance of the abstract class. That contradicts the definition of an abstract class and therefore can't be done.



回答4:

It's only bad design because it's a forced decision, what if you want a subclass that has non-serializable members.

That's why.

E.g. List is not Serializable, but every major list implementation is. (I know list is a Interface, but a abstract class with no members =/= a interface)