Why not serialize abstract classes in Java?

16,061

Solution 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.

Solution 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...

Solution 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.

Solution 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)

Share:
16,061
athena
Author by

athena

Updated on June 11, 2022

Comments

  • athena
    athena almost 2 years

    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.

  • Eric Petroelje
    Eric Petroelje over 13 years
    +1, was about to say the same thing a bit differently, but your answer illustrates it much more succinctly than I what I would have said.
  • Brett
    Brett over 13 years
    If you deserialised the object, it's class would be the same as the object that was serialised (give or take writeReplace/readResolve).
  • DwB
    DwB over 13 years
    I believe your argument is flawed. It is not possible to instantiate an abstract class. Therefore, it is never possible that you need to de-serialize an astract class. Any de-serialization of an abstract class will be in the context of a derived concrete class which means, the class is known at the point of de-serialization.
  • Babak Naffas
    Babak Naffas over 13 years
    @Tom, @dwb, I agree with your statements. And in these scenarios, the derived class would need to be serialized, not the base class.
  • Brett
    Brett over 13 years
    @Babak Naffas No the base class really does need to be serialised if it contains data.
  • Brett
    Brett over 13 years
    @athena You really don't want methods like that in an API.
  • Sergei Tachenov
    Sergei Tachenov over 13 years
    Implementing Serializable in the base class just says that all its subclasses must be serializable too. I think it's just a part of contract and can be even applied to interfaces. So I don't get it too why it's bad (or is it?).
  • athena
    athena over 13 years
    I want all subclasses to be Serializable. The abstract class has fields. In this situation, is it better to make the abstract class Serializable?
  • athena
    athena over 13 years
    Why not? I want all subclasses to be Serializable. The abstract class has fields. In this situation, is it better to make the abstract class Serializable(with custom read write methods)?
  • Bozho
    Bozho over 13 years
    looking at the collection framework - no ;) AbstractList is not serializable. But it is not such a great difference anyway.
  • Brett
    Brett over 13 years
    @athena I suggest making the base class serialisable, whether accepting the default serial form or providing another. Adding methods that allow other classes to read and write fields is going to be bad.
  • athena
    athena over 13 years
    Thanks for pointing out that the methods might cause problems.