ObjectOutputStream in Java
The ObjectOutputStream is used to serialize objects arrays and other values to a stream. The writeObject() method serializes an object or array and various other methods are used to write primitive data values to the stream.
Note only objects that implement the Serializable interface or the Externalizable interface can be serialized.
The defaultWriteObject() method may only be called from the writeObiect() method of a Serializable object. It allows an object to perform additional processing before or after serializing itself.
The remaining methods of ObjectOutputStream are miscellaneous stream manipulation methods and protected methods for use by subclasses that want to customize its serialization behavior.
The ObjectOutputStream class can write both primitive types and object instances to an underlying OutputStream.The objects and other data can then be read by an ObjectInputStream. These two classes provide persistent storage of objects when they are used in conjunction with FileInputStream and FileOutputStream. The classes can also be
used with socket streams to pass objects across the network.
Only objects that are instances of classes that implement the Serializable or Externalizable interfaces can be serialized to an output stream. The default serialization mechanism is implemented by writeObject().
When an object is serialized, the class of the object is encoded, along with the class name, the signature of the class, the values of the non-static and non-transient fields of the object, including any other objects referenced by the object (except those that do not implement the Serializable interface themselves).
Multiple references to the same object are encoded using a reference sharing mechanism, so that a graph of the object can be restored appropriately. Strings and arrays are objects in Java, so they are treated as objects during serialization.
The Class Structure of the ObjectOutputStream is given as
public class java.io.ObjectOutputStream extends java.io.OutputStream implements java.io.ObjectOutput{
// Public Constructor;
public ObjectOutputStream(OutputStream out) throws IOException;
// Public Instance Methods
public void close() throws IOException;// Overrides OutputStream
public final void defaultWriteObject() throws IOException;
public void flush() throws IOException;// Overrides OutputStream
public void reset() throws IOException;
public void write(int data) throws IOException;// Defines OutputStream
public void write(byte[ ] b) throws IOException;// Overrides OutputStream
public void write(byte[ ] b, int off, int len) throws IOException; //Overrides OutputStream
public void writeBoolean(boolean data) throws IOException;// FromDataOutput;
public void writeByte(int data) throws IOException; // From DataOutput
public void writeBytes(String data) throws IOException;// From DataOutput
public void writeChar(int data)throws IOException;// From DataOutput
public void writeChars(String data) throws IOException;// From DataOutput
public void writeDouble(double data) throws IOException;// From DataOutput
public void writeFloat(float data) throws IOException;// From DataOutput
public void writeInt(int data) throws IOException;// From DataOutput
public void writeLong(long data) throws IOException;// From DataOutput
public final void writeObject(Object obj) throws IOException;// From ObjectOutput
public void writeShort(int data) throws IOException;// From DataOutput
public void writeUTF(String data) throws IOException;// From DataOutput
// Protected Instance Methods
protected void annotateClass(Class cl) throws IOException;
protected final boolean enableReplaceObject((boolea enable) throws SecurityException;
protected void drain() throws IOException;
Pocected Object replaceObject(Obiect obi) throws IOException;
protected void writeStreamHeader() throws IOException;
}
The details of the structure is given as:
public ObjectOutputStream(OutputStream out) throws IOException;
public ObjectOutputStream(OutputStream out) throws IOException constructor creates an ObjectOutputStream that writes to the given output stream. The constructor writes the stream header, which consists of a magic number and version number, in preparation for serialization.
Parameter
out-The underlying output stream.
public void close() throws IOException;// Overrides OutputStream
public void close() throws IOException; method closes the stream and releases any system resources that are associated with it.
public final void defaultWriteObject() throws IOException;
public final void defaultWriteObject() throws IOException method writes the fields of the object that are not static or transient. The method can only be called from the private writeObject() method of an object that is being serialized; it throws a NotActiveException if it is called at any other time. This method implements the default serialization mechanism.
public void flush() throws IOException;// Overrides OutputStream
public void flush() throws IOException; method takes any buffered output and forces it to be written to the underlying stream.
public void reset() throws IOException;
public void reset() throws IOException method sets the state of the ObjectOutputStream to the same state as when it was created.
As objects are serialized to the stream, the ObjectOutputStream remembers which ones are already serialized. If the program requests that already serialized objects be written again, the ObjectOutputStream just writes out a reference to the previous object.
Calling reset() causes the ObjectOutputStream to forget what it has done before, so all subsequent objects are fully serialized.
public void write(int data) throws IOException;// Defines OutputStream
public void write(int data) throws IOException method writes the lowest eight bits of b to the underlying stream as a byte.
Parameter
data-The value to write.
public void write(byte[ ] b) throws IOException;// Overrides OutputStream
public void write(byte[ ] b) throws IOException method writes the given array of bytes to the underlying stream.
Parameter
b-An array of bytes to write.
public void write(byte[ ] b, int off, int len) throws IOException; //Overrides OutputStream
public void write(byte[ ] b, int off, int len) throws IOException method writes len bytes from the given array, starting off elements from the beginning of the array, to the underlying stream.
Parameter
b-An array of bytes to write to the stream.
off-An offset into the byte array.
len-The number of bytes to write.
public void writeBoolean(boolean data) throws IOException;// FromDataOutput;
public void writeBoolean(boolean data) throws IOException method writes a byte that contains the value 1 to the underlying stream if data is true. If data is false, the method writes a byte that contains the value 0.
Parameter
data-The value to write.
public void writeByte(int data) throws IOException; // From DataOutput
public void writeByte(int data) throws IOException method writes an 8-bit byte to the underlying stream, using the lowest eight bits of the given integer data.
Parameter
data-The int value to write.
public void writeBytes(String data) throws IOException;// From DataOutput
public void writeBytes(String data) throws IOException method writes the characters in the given String to the underlying stream as a sequence of 8-bit bytes. The high-order bytes of the characters in the string are ignored.
Parameter
data-The String value to write.
public void writeChar(int data)throws IOException;// From DataOutput
public void writeChar(int data)throws IOException method writes a 16-bit char to the underlying stream, using the lowest two bytes of the given integer data.
Parameter
data-The value to write.
public void writeChars(String data) throws IOException;// From DataOutput
public void writeChars(String data) throws IOException method writes the characters in the given String object to the underlying stream as a sequence of 16-bit characters.
Parameter
data-The String value to write.
public void writeDouble(double data) throws IOException;// From DataOutput
public void writeDouble(double data) throws IOException method writes a 64-bit double to the underlying stream. The double value is converted to a long using doubleToLongBits() of Double; the long value is then written to the underlying stream as eight bytes with the highest byte first.
Parameter
data-The double value to write.
public void writeFloat(float data) throws IOException;// From DataOutput
public void writeFloat(float data) throws IOException method writes a 32-bit float to the underlying stream. The float value is converted to a int using floatToIntBits() of Float; the int value is then written to the underlying stream as four bytes with the highest byte first.
Parameter
data-The float value to write.
public void writeInt(int data) throws IOException;// From DataOutput
public void writeInt(int data) throws IOException method writes a 32-bit int to the underlying stream. The value is written as four bytes with the highest byte first.
Parameter
data-The int value to write.
public void writeLong(long data) throws IOException;// From DataOutput
public void writeLong(long data) throws IOException method writes a 64-bit long to the underlying stream. The value is written as eight bytes with the highest byte first.
Parameter
data-The long value to write.
public final void writeObject(Object obj) throws IOException;// From ObjectOutput
public final void writeObject(Object obj) throws IOException method serializes the given object to the stream. The class of the object is encoded, along with the class name, the signature of the class, the values of the non-static and non-transient fields of the object, including any other objects referenced by the object (except those that do not implement the Serializable interface themselves).
Multiple references to the same object are encoded using a reference sharing mechanism so that a graph of the object can be restored appropriately.
Parameter
obj-The object to write or The object to be serialized..
public void writeShort(int data) throws IOException;// From DataOutput
public void writeShort(int data) throws IOException method writes a 16-bit short to the underlying stream, using the lowest two bytes of the given integer data.
Parameter
data-The value to write.
public void writeUTF(String data) throws IOException;// From DataOutput
public void writeUTF(String data) throws IOException method writes the given String to the underlying stream using the UTF-8 encoding.
Parameter
data-The string value to write.
protected void annotateClass(Class cl) throws IOException;
protected void annotateClass(Class cl) throws IOException method is called once for each unique class during serialization. The implementation in ObjectOutputStream does nothing; subclasses can override this method to write out more information about a class. A corresponding subclass of ObjectInputStream should override the resolveClass() method to read the extra class information.
Parameter
cl-The class to be serialized.
protected final boolean enableReplaceObject((boolea enable) throws SecurityException;
protected final boolean enableReplaceObject((boolea enable) throws SecurityException method determines if a trusted subclass of ObjectOutputStream is allowed to replace serialized objects. If the method is called with true, replacement is enabled. Each time an object is serialized, replaceObject() is called to give the ObjectOutputStream a chance to replace the object. A trusted stream is one whose class has no ClassLoader.
This method returns true if object replacement was previously enabled; false otherwise.
Parameter
enable-A boolean value that specifies whether or not object replacement is enabled.
protected void drain() throws IOException;
protected void drain() throws IOException method is a helper method for flush(). It forces a write of any buffered data in the ObjectOutputStream, but does not call flush() on the underlying stream.
Pocected Object replaceObject(Obiect obi) throws IOException;
Pocected Object replaceObject(Obiect obi) throws IOException method is called with each object to be serialized to give the stream a chance to replace the object. In ObjectOutputStream,this method simply returns the object that was passed to it. Subclasses can override this method to provide more useful functionality.
This is applicable only If object replacement is enabled for this ObjectOutputStream.
This method returns a replacement for the given object.
Parameter
obj-The object to be replaced.
protected void writeStreamHeader() throws IOException;
protected void writeStreamHeader() throws IOException method writes the serialization stream header, which consists of a magic number and a version number. This method is called by the constructor for ObjectOutputStream. If you subclass ObjectOutputStream, We can override this method to provide your own stream header.
Apart from these ObjectOutputStream class inherits the below methods from Object class:
- clone()
- finalize()
- hashCode()
- notifyAll()
- wait()
- wait(long, int)
- equals(Object)
- getClass()
- notify()
- toString()
- wait(long)
An Example of ObjectOutputStream class is given as
The below code snippet will open a myTextstore and store a Color object
FileOutputStream myFileOut;
ObjectOutputStream myOut;
try {
myFileOut= new FileOutputStream("c:\\Test\\myTextstore.ser");
myOut= new ObjectOutputStream(fileOut);
myOut.writeObject(Color.blue);
myOut.close();
}
catch (IOException e) {
System.out.println("Error writing: " + e);
}
Classes that require special handling during serialization and deserialization must implement the following methods (with these exact signatures):
private void readObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream stream) throws IOException;
The writeObject() method is responsible for writing the state of the object for the particular class so that it can be restored by readObject(). The writeObject() method does not need to handle writing the state for the object’s superclass or any of its subclasses except in the case where the superclass does not itself implement the serializable interface.
In this case, the nonserializable class must have a no-argument constructor that can be called to initialize its fields, and it is the responsibility of the subclass to save the state of its superclass.
A class that inherits the implementation of Serializable prevents itself from being serialized by defining readObject() and writeObject() methods that throw NotSerializableException objects.
If a class needs complete control over the contents and formatting of the serialized form of its objects, it should implement the Externalizable interface.
ObjectOutputStream in Serialization
Let us create a class that we want to Serialize using Serializable interface.
import java.io.*;
public class MySerialization implements Serializable {
public int x=5;
transient int y=10;
private float z= 2.0f;
int getX() {
return x;
}
int getY()
{
return y;
}
float getZ() {
return z;
}
}
Check here we have a transient data y.
Now lets us create a class that helps in Serialization
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class MyDemoSerialization {
public static void main(String[] args) {
MySerialization ms= new MySerialization();
System.out.println("value of x "+ms.getX());
System.out.println("value of y "+ms.getY());
System.out.println("value of z "+ms.getZ());
try {
FileOutputStream fos=new FileOutputStream("D:\\MyCode\\abc.ser");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(ms);
oos.close();
System.out.println("Serialization is done");
}
catch(Exception e) {e.printStackTrace();}
}
}
The output of the code:
value of x 5
value of y 10
value of z 2.0
Serialization is done
the y value is printed before Serialization
 100vw, 765px” /><figcaption id=)
Now let us DeSerializa the same
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class MyDeSerialization {
public static void main(String[] args) {
System.out.println("Deserialization starts");
MySerialization ms = null;
try {
FileInputStream fis=new FileInputStream("D:\\MyCode\\abc.ser");
ObjectInputStream ois=new ObjectInputStream(fis);
ms = (MySerialization)ois.readObject();
ois.close();
}
catch(Exception e) {e.printStackTrace();}
System.out.println("value of x "+ms.getX());
System.out.println("value of y "+ms.getY());
System.out.println("value of z "+ms.getZ());
}
}
The output of the code:
Deserialization starts
value of x 5
value of y 0
value of z 2.0
Check the y value is not saved as it is transient.