Controlling Java Serialization.

How to make more control of the Serialization?

  • Classes that need to completely control the serialization process can implement java.io.Externalizable, which extends java.ioSerializable.
  • java.io.Externalizable declares readExternal() and writeExternal() methods for you to implement and handle the serialized reading and writing.
  • This interface (java.io.Externalizable) completely replaces the default serialization behavior for assembling and disassembling the component elements. This involves the following:
    1. An java.io.Externalizable class must provide a no-argument contructor which is invoked before readExternal() method.
    2. The readExternal() and writeExternal() methods must explicitly read and write any data necessary to reconstruct the object.
      (this includes data members from object of the class and all its objects of superclasses)
    3. readObject() and writeObject() methods will not be called on the class or any super class, and defaultReadObject() and defaultWriteObject() methods are not available.
    4. The java.io.ObjectStreamClass and internal handle are used in the same way as they are for java.io.Serializable classes

Example in how to completely control the serialization of java objects:

First a class, Rectangle, that is NOT made serializable and have no default constructor:
package app;
public class Rectangle  {
  private int length;
  private int width;

  public Rectangle(int width, int length) {
   this.length=length;
   this.width=width;
  }

  @Override
  public String toString() {
    return  " width: " + width + " length: " + length;
  }

  public int getLength() {
    return length;
  }

  public void setLength(int length) {
    this.length = length;
  }

  public int getWidth() {
    return width;
  }

  public void setWidth(int width) {
    this.width = width;
  }
}
Second a class, Box, that extends the Rectangle class and is made Externalizable:
package app;

import java.io.*;

public class Box extends Rectangle implements Externalizable {
  private int height;
//  required no-argument constructor for Externalizable mechanism
  public Box() {
    // Remember that the Rectangle class has not any no-argument constructor
    this(0, 0, 0);  // calls the next in the is class constructor w/arguments
  }
  public Box(int width, int length, int height) {
    super(width, length); // calls the superclass constructor w/arguments
    this.height = height;
  }
// reads the serialized data
  public void readExternal(ObjectInput in) throws IOException {
    setHeight(in.readInt());
    setWidth(in.readInt());
    setLength(in.readInt());
  }
// write the serialized data
  public void writeExternal(ObjectOutput out) throws IOException {
    out.writeInt(getHeight());
    out.writeInt(getWidth());
    out.writeInt(getLength());
  }

  @Override
  public String toString() {
    return "Height: " + height+ super.toString();
  }

  public int getHeight() {
    return height;
  }

  public void setHeight(int height) {
    this.height = height;
  }
}
here is a main class to write the serializable object of a Box to a file Box.ser:
package app;

import java.io.*;

public class WriteCust {
  public static void main(String args[]) {
    Box mybox = new Box(11, 200, 40);
    ObjectOutputStream out = null;
    try {
      out = new ObjectOutputStream(new FileOutputStream("box.ser"));
      out.writeObject(mybox);
      System.out.println("Wrote \"" + mybox + "\" to file");
    }
    catch (IOException e) {
      System.err.println("Error writing object: " + e.getMessage());
    }
    finally {
      try {
        out.close();
      }
      catch (IOException e) {
        System.err.println(e.getMessage());
      }
    }
  }
}
Here's console printout:
Wrote "Height: 40 width: 11 length: 200" to file
Here is the hexadecimal representation of the Box.ser file:
AC ED 00 05 73 72 00 07 61 70 70 2E 42 6F 78 6F 
74 99 4E 74 FF 5F 21 0C 00 00 78 70 77 0C 00 00 
00 28 00 00 00 0B 00 00 00 C8 78
Here is a main class to read the serializable object of a Box from the file Box.ser:
package app;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ReadCust {
  public static void main(String args[]) {

    ObjectInputStream in = null;
    try {
      in = new ObjectInputStream(new FileInputStream("box.ser"));
      Box mybox = (Box) in.readObject();
      System.out.println("Read \"" + mybox + "\" from file");
    }
    catch (ClassCastException e) {
      System.err.println("Error casting object to a Box");
    }
    catch (ClassNotFoundException e) {
      System.err.println("Class not found");
    }
    catch (IOException e) {
      System.err.println("Error reading object: " + e.getMessage());
    }
    finally {
      try {
        in.close();
      }
      catch (IOException e) {
        System.err.println(e.getMessage());
      }
    }
  }
}
Here's console printout:
Read "Height: 40 width: 11 length: 200" from file
You can download this example here (needed tools can be found in the right menu on this page).
© 2010 by Finnesand Data. All rights reserved.
This site aims to provide FREE programming training and technics.
Finnesand Data as site owner gives no warranty for the correctness in the pages or source codes.
The risk of using this web-site pages or any program codes from this website is entirely at the individual user.