Serialization inheritance in J2SE

Time:2021-12-27

When a parent class implements the serializable interface, its subclasses will automatically implement serialization.

This is verified by the following:

  package Serial;
  import java.io.Serializable;
Public class Super C implements serializable {/ / the parent class implements serialization
  int supervalue;
  public SuperC(int supervalue) {
  this.supervalue = supervalue;
  }
  public String toString() {
  return “supervalue: “+supervalue;
  }
  }

Public class Subc extensions superc {/ / subclasses
  int subvalue;

  public SubC(int supervalue,int subvalue) {
  super(supervalue);
  this.subvalue=subvalue;
  }

  public String toString() {
  return super.toString()+” sub: “+subvalue;
  }
  }

  public class Test1 {

  public static void main(String [] args){
  SubC subc=new SubC(100,200);
  FileInputStream in=null;
  FileOutputStream out=null;
  ObjectInputStream oin=null;
  ObjectOutputStream oout=null;
  try {
   out = new FileOutputStream(“Test1.txt”);// Subclass serialization
   oout = new ObjectOutputStream(out);
   oout.writeObject(subc);
   oout.close();
   oout=null;

   in = new FileInputStream(“Test1.txt”);
   oin = new ObjectInputStream(in);
   SubC subc2=(SubC)oin. readObject();// Subclass deserialization
   System.out.println(subc2);
  } catch (Exception ex){
   ex.printStackTrace();
  } finally{
… omitted here
  }
  }
  }

The operation results are as follows:

  supervalue: 100 sub: 200

It can be seen that the subclass was successfully serialized / deserialized.

How to serialize subclasses seems to be a very simple thing, but sometimes we can’t let the parent class implement the serializable interface, because sometimes the parent class is abstract (it doesn’t matter), and the parent class can’t force each subclass to have the ability of serialization. In other words, the parent class is designed only to be inherited.

To write a serializable subclass for a parent class that does not implement the serializable interface is a very troublesome thing. Java docs mentions:

  “To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype’s public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class’s state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime. ”

In other words, to write a serializable subclass for a parent class that does not implement the serializable interface, you need to do two things:

First, the parent class should have a parameterless constructor;

Second, the subclass should be responsible for serializing (deserializing) the domain of the parent class.

We remove the serializable interface of superc and add the serializable interface to Subc. Error after running:

  java.lang.Error: Unresolved compilation problem:
  Serializable cannot be resolved or is not a valid superinterface
  at Serial.SubC.(SubC.java:15)
  at Serial.Test1.main(Test1.java:19)
  Exception in thread “main”

As mentioned in docs, it is impossible for a parent class to lack a parameterless constructor.

Next, we rewrite this example as suggested in docs:

  public abstract class SuperC {
  int supervalue;
  public SuperC(int supervalue) {
  this.supervalue = supervalue;
  }
Public superc() {} / / add a parameterless constructor
  public String toString() {
   return “supervalue: “+supervalue;
  }
  }

  public class SubC extends SuperC implements Serializable {
  int subvalue;

  public SubC(int supervalue,int subvalue) {
   super(supervalue);
   this.subvalue=subvalue;
  }

  public String toString() {
   return super.toString()+” sub: “+subvalue;
  }

  private void writeObject(java.io.ObjectOutputStream out)
  throws IOException{
   out. defaultWriteObject();// Serialize object first
   out. writeInt(supervalue);// Re serialize the domain of the parent class
  }
  private void readObject(java.io.ObjectInputStream in)
  throws IOException, ClassNotFoundException{
   in. defaultReadObject();// Deserialize the object first
   supervalue=in. readInt();// Then deserialize the domain of the parent class
  }
  }

The running results show that this method is correct. Here we use the writeobject / readObject method. If this pair of methods exist, they will be called during serialization, Instead of the default behavior (we’ll discuss it later and learn so much first). When serializing, we first call the defaultwriteobject of objectoutputstream, which uses the default serialization behavior, and then serialize the domain of the parent class; the same is true when deserializing.

To sum up:

Purposeful behavior

For a parent class that implements the serializable interface, write a subclass that can be serialized. The subclass will automatically implement serialization

For a parent class that does not implement the serializable interface, write a serializable subclass 1. The parent class must have a parameterless constructor; 2. The subclass should serialize itself first, and then the subclass should be responsible for serializing the domain of the parent class

Recommended Today

Analysis of multithreading in IOS development

What is your understanding of multithreading development? There are several ways to implement multithreading in IOS? Basic concepts program An executable application generated from source code process A process is the program itself. A running program can be regarded as a process thread A thread is a code segment in which a program runs independently […]