ObjectOutputStream example: A Java object serialization tutorial
Java object serialization is a feature of the JDK that is far too often overlooked. When a developer puts together a prototype or cooks up a proof of concept, simply saving a serialized Java object to the local file-system, rather than integrating a NoSQL database or a relational system to provide persistence, is a serious time saver. This ObjectOutputStream example will demonstrate just how easy it is to integrate Java object serialization and deserialization into your applications.
The Java serialization tutorial
In this Java serialization example, we will use both the ObjectOutputStream and the ObjectInputStream to save and retrieve the state of a simple JavaBean. The POJO will be serialized and deserialized to and from the local file-system.
For this Java serialization tutorial, we will to create a simple Score class. This class will model the score of a rock-paper-scissors game, with properties that count the number of wins, losses and ties that have occurred. There will be getter methods for properties, but there will be no setters. The number of wins, losses and ties maintained by the Score class can only be incremented by one at a time, so instead of setter methods, the Java serialization object will have methods called increaseWins, increaseTies and increaseLosses. The full class is coded below:
/* Java serialization example class */ package com.mcnz.serialization.tutorial; import java.io.*; public class Score implements java.io.Serializable { private static final long serialVersionUID = 1L; int wins, losses, ties; public Score() {} /* No need for setters and getters in this * Java object serialization tutorial. We * will 'punch up' the class used for the * ObjectOutputStream example at the end * of this Java object serialization example.*/ } /* End of Java serialization tutorial class */
Java object serialization
Before you can perform Java object serialization, you first need to create an instance of the class. A call to the the constructor of the class to be serialized achieves this.
Score score = new Score();
You then need to decide the destination of the serialized instance. Will Java object serialization target the file-system? Will the Java object serialized across a network? Will the serialized Java object be delivered to an external system. In this case we will perform file-system based Java object serialization. That means we must create an instance of a FileOutputStream and point it at a file on the file-system.
FileOutputStream fileOut = new FileOutputStream("C:\\temp\\score.ser");
As seen in the Java code above, the serialized Java instance will have its state written to a file named score.ser, which sits in a temp directory off the root of the C: drive. This file must be created first before you run the example, lest the program will throw a runtime exception.
ObjectOutputStream example
With the FileOutputStream created, we simply pass the instance to the constructor of the ObjectOutputStream. The combination of the FileOutputStream and the ObjectOutputStream will allow Java object serialization to happen at the file level.
ObjectOutputStream out = new ObjectOutputStream(fileOut);
With the ObjectOutputStream created an initialized, all that’s left to do is to perform Java serialization on the instance. Pass the score object as a parameter to the ObjectOutputStream’s writeObject method to achieve this:
out.writeObject(score);
Close the ObjectOutputStream
When Java object serialization is complete, both the ObjectOutputStream and the FileOutputStream can be closed.
out.close(); fileOut.close();
After we add the requisite catch block, the complete ObjectOutputStream example looks as follows:
/* Start of Java serialization example class */ class JavaSerializationExample { public static void main (String args[]) { Score score = new Score(); saveScore(score); } public static void saveScore(Score score) { try { FileOutputStream fileOut = new FileOutputStream("C:\\score01.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(score); out.close(); fileOut.close(); } catch (Exception e) { e.printStackTrace(); } } } /* End of Java serialization tutorial class */
Java deserialization example
Of course, Java object serialization is only half of the job. The other half is Java object deserializtion, which we accomplish with the FileInputStream and the ObjectInputStream.
The first step to perform in Java object deserialization is to declare a blank instance of the Score class to be initialized. Since we expect the JVM to perform Java deserialization, we don’t need to create an instance of the Score class, but instead, we declare an instance and wait for the Java deserialization process to initialize it.
Score score = null;
File based ObjectInputStream example
The next step is to point an instance of the FileInputStream at the file that was created by the serialization process. That FileInputstream is then passed into the constructor of an ObjectInputStream.
FileInputStream fileIn = new FileInputStream("C:\\score.ser"); ObjectInputStream in = new ObjectInputStream(fileIn);
With the ObjectInputStream initialized, Java deserialization occurs simply through invocation of the ObjectInputStream’s readObject method:
score = (Score) in.readObject();
When Java deserialization is complete, the ObjectInputStream and the FileInputStream can both be closed.
in.close(); fileIn.close();
When it is all put together, the code looks as follows:
/* Java object deserialization example class */ class JavaDeserializationExample { public static void main (String args[]) { Score score = new Score(); saveScore(score); } public static Score getScore() { Score score = null; try { FileInputStream fileIn = new FileInputStream("C:\\score01.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); score = (Score) in.readObject(); in.close(); fileIn.close(); } catch (Exception e) { System.err.println("\nError creating Score object. None exists?\n" + e.getMessage() + e.getClass()); } if (score == null) { score = new Score(); JavaSerializationExample.saveScore(score); } return score; } } /* End of Java object deserialization tutorial class */
You will notice at the end of the getScore() method that there is a check to see if the score instance is still null. If it is, then Java deserialization has failed, which most likely is due to the fact that an instance of the Score class has never been subject to Java object serialization in the first place. To account for that possibility, if the instance does come back null, a new instance is created and serialized. Future attempts to deserialize this instance will succeed.
And that’s it. This ObjectInputStream and ObjectOutputStream example demonstrates just how easy it is to perform Java object serialization and deserialization.
The Java object serialization example source code
The full code for this Java serialization tutorial is below. This is code uses a single public class and two non-public classes, all of which can be written and saved in a single Java file named Score.java
package com.mcnz.ioc.example; import java.io.*; /* The Java serialization tutorial class. */ /* Notice we have added getters and increase methods to the * class used to demonstrate Java object serialization. We left * these methods out earlier to keep the ObjectOutputStream example * more concise. */ public class Score implements java.io.Serializable { private static final long serialVersionUID = 1L; int wins, losses, ties; public Score() {} public void increaseWins() { this.wins++; } public void increaseLosses() { this.losses++; } public void increaseTies() { this.ties++; } public void reset() { wins=losses=ties=0; } public int getWins() { return wins; } public int getLosses() { return losses; } public int getTies() { return ties; } } /* End of Java serialization tutorial class */ /* ObjectOutputStream Example */ class JavaSerializationExample { public static void main (String args[]) { Score score = new Score(); score.increaseWins(); score.increaseTies(); saveScore(score); System.out.println(score.getTies()); } public static void saveScore(Score score) { try { FileOutputStream fileOut = new FileOutputStream("C:\\temp\\score.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(score); out.close(); fileOut.close(); } catch (Exception e) { e.printStackTrace(); } } } /* End of ObjectOutputStream example tutorial */ /* ObjectInputStream Example */ class JavaDeserializationExample { public static void main (String args[]) { Score score = null; score = JavaDeserializationExample.getScore(); System.out.println(score.getWins()); System.out.println(score.getLosses()); System.out.println(score.getTies()); } public static Score getScore() { Score score = null; try { FileInputStream fileIn = new FileInputStream("C:\\temp\\score.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); score = (Score) in.readObject(); in.close(); fileIn.close(); } catch (Exception e) { System.err.println("\nError creating Score object. None exists?\n" + e.getMessage() + e.getClass()); } if (score == null) { score = new Score(); JavaSerializationExample.saveScore(score); } return score; } } /* End of ObjectInputStream example tutorial */