Serialization of objects. The transient keyword. Examples
Contents
- 1. What is serialization? Advantages of serialization
- 2. Implementing Serialization in Java Programs
- 3. What is the purpose of the transient modifier?
- 4. An example of serializing and using the transient modifier. Classes ObjectInputStream and ObjectOutputStream
- 5. Are class methods saved during serialization?
- 6. An example of a class that contains methods for serializing an instance of this class
- Related topics
Пошук на інших ресурсах:
1. What is serialization? Advantages of serialization
The Java programming language has powerful facilities for providing a serialization mechanism. Serialization is the ability of an object to save its own data (object state) in a byte stream in order to further restore this data (state) during the next program starts. In other words, the current values of internal variables in an object can be saved (for example, to a file), and then restored at the right time.
The serialization mechanism provides the following benefits:
- the object to be serialized exists between program runs. This mechanism is called lightweight persistence. The object is first saved to disk, then restored to its initial state the next time the program is started;
- provides remote invocation of Java methods, which allows you to work with objects that are “located” on remote computers as if they existed on your computer;
- the need to save the current information about the state of the visual JavaBeans;
- use in objects of classes that require maintaining the current state.
⇑
2. Implementing Serialization in Java Programs
In the Java language, in order to serialize an object in a program, you need to adhere to the following recommendations. All classes related to serialization must implement the Serializable interface. This means that the class that implements serialization should look something like this:
class MySerializeClass implements Serializable { ... }
so the class, the instance of which is serialized, must also implement the Serializable interface:
class MyDataClass implements Serializable { ... }
⇑
2.1. Writing an object to a file
If a dataObj object of some DataClass class is created, then to save this object you need to perform the following actions.
1. Create a source stream fOut of type OutputStream. If the object is saved to a file, an initial stream of type FileOutputStream is created
FileOutputStream fOut = new FileOutputStream(filename);
where filename is the name of the file where the object will be saved.
The FileOutputStream class is a subclass of the abstract OutputStream class.
2. Pack fOut file object to another object type ObjectOutputStream
ObjectOutputStream objOut = new ObjectOutputStream(fOut);
The result is a stream of objOut.
3. Write an instance of dataObj to the objOut stream. For this, the built-in writeObject() method is used.
objOut.writeObject(dataObj);
4. Close both created streams
objOut.close(); fOut.close();
⇑
2.2. Reading an object from a file
If the object was previously saved, then in order to restore its state from the file, you need to perform the following steps.
1. Create an instance of fInput of the FileInputStream class
FileInputStream fInput = new FileInputStream(filename);
where filename is the name of the file (type String) in which the object was previously saved.
2. Create an instance of objInput of the ObjectInputStream class, into which to wrap the fInput instance of the FileInputStream class
ObjectInputStream objInput = new ObjectInputStream(fInput);
3. Read an instance using the readObject() method. For example, if you need to read an instance of the DataClass class, then the reading code will be as follows
DataClass dObj = (DataClass)objInput.readObject();
4. Close streams fInput and objInput
objInput.close(); fInput.close();
⇑
3. What is the purpose of the transient modifier?
The transient modifier is used when it becomes necessary to save an object (instance) of a class (to perform serialization). The transient modifier is set before the declaration of an internal class variable, the value of which should not be stored if the object is saved. Using the transient modifier, you can programmatically specify data that does not need to be saved when the object is serialized.
For example. In the following Book class, the price variable is declared with the transient modifier. This means that when writing to a file of any instance of the Book class, the values of the title, author, year variables will be written, except for the price variable.
class Book { String title; String author; int year; transient double price; // This variable will not be saved }
⇑
4. An example of serializing and using the transient modifier. Classes ObjectInputStream and ObjectOutputStream
The example declares two classes:
- the DataClass containing the data to be stored. An instance of this class is saved;
- the SerializeClass class, which contains methods for writing an instance of the DataClass type. Both classes implement the Serializable interface.
The DataClass class declares:
- internal variables a, b. The variable b is declared as a transient variable. This means that when writing an instance of the DataClass type to a file, the value of the b variable will not be written;
- constructor DataClass(int, int);
- methods for access to internal variables GetA(), GetB(), SetA(), SetB();
- the Print() method, which outputs the value of internal variables.
The SerializeClass class declares:
- the SaveData() method, which implements writing an instance of the DataClass type to a file;
- the ReadData() method, which returns an instance of the DataClass type that was previously written to the file.
// Serialization of objects import java.io.*; // The class, the instance of which will need to be written/read from the file class DataClass implements Serializable { // Internal variables private int a; private transient int b; // this variable will not be saved // Constructor DataClass(int a, int b) { this.a = a; this.b = b; } // Access methods int GetA() { return a; } int GetB() { return b; } void SetA(int a) { this.a = a; } void SetB(int b) { this.b = b; } // Method that outputs data void Print() { System.out.println("a = " + a + ", b = " + b); } } // A class that contains methods for serializing (writing/reading data) of the DataClass public class SerializeClass implements Serializable { // A method that writes an instance of the DataClass class to the file filename static void SaveData(DataClass dataObj, String filename) throws ClassNotFoundException, IOException { // 1. Create an instance of the FileOutputStream class - create a file stream FileOutputStream fOut = new FileOutputStream(filename); // 2. Create an instance of objOut of the ObjectOutputStream class - a stream of writing objects ObjectOutputStream objOut = new ObjectOutputStream(fOut); // 3. Write a dataObj instance to the objOut stream // 3.1. Write a comment objOut.writeObject("Storage the dataObj instance\n"); // 3.2. Write instance objOut.writeObject(dataObj); // 4. Close the objOut stream objOut.close(); // 5. Close the fOut stream fOut.close(); } static DataClass ReadData(String filename) throws ClassNotFoundException, IOException { // 1. Create an instance of FileInputStream class FileInputStream fInput = new FileInputStream(filename); // 2. Create an instance of ObjectInputStream class ObjectInputStream objInput = new ObjectInputStream(fInput); // 3. Read data from the file named filename to dataObj instance // 3.1. Read the comment String s = (String)objInput.readObject(); // 3.2. Read the instance of DataClass class DataClass dObj = (DataClass)objInput.readObject(); // 4. Close streams objInput.close(); fInput.close(); // 5. Return the result return dObj; } public static void main(String[] args) throws ClassNotFoundException, IOException { // 1. Write the instance of DataClass class to "myFile.dat" file // 1.1. Create an object of DataClass class DataClass objData = new DataClass(5, 8); // 1.2. Write object objData to "myFile.dat" file SaveData(objData, "myFile.dat"); // 2. Read the instance of DataClass from file "myFile.dat" // 2.1. Declare the reference to DataClass DataClass objData2; // 2.2. Read data to objData2 objData2 = ReadData("myFile.dat"); // 2.3. Print data objData2.Print(); // a = 5, b = 0 - the value of the variable b was not written } }
⇑
5. Are class methods saved during serialization?
No. When using the serialization mechanism, only data (internal variables) are saved.
⇑
6. An example of a class that contains methods for serializing an instance of this class
In the example, the Sphere class is developed, in which the methods are defined:
- writing to the file of the current instance of the class;
- reading data from the file of the current class.
The class contains methods for serializing an instance of this class.
The class text is as follows
// A class containing methods for serializing an object of this class import java.io.*; class Sphere implements Serializable { // Internal variable - the radius of a sphere private double radius; // Access methods public double GetR() { return radius; } public void SetR(double radius) { this.radius = radius; } // Methods for serializing an object of this class public void SaveToFile(String filename) throws ClassNotFoundException, IOException { // 1. Create an instance of FileOutputStream class - create file stream FileOutputStream fOut = new FileOutputStream(filename); // 2. Create instance objOut of class ObjectOutputStream - objects write stream ObjectOutputStream objOut = new ObjectOutputStream(fOut); // 3. Write the current instance to the objOut stream objOut.writeObject(this); // 4. Close the objOut stream objOut.close(); // 5. Close the file stream fOut.close(); } public Sphere ReadFromFile(String filename) throws ClassNotFoundException, IOException { // 1. Create an instance of FileInputStream class FileInputStream fInput = new FileInputStream(filename); // 2. Create an instance of ObjectInputStream class ObjectInputStream objInput = new ObjectInputStream(fInput); // 3. Read data from filename to insnance dObj Sphere dObj = (Sphere)objInput.readObject(); // 4. Close streams objInput.close(); fInput.close(); // 5. Return the result return dObj; } // Method of calculating the volume of a sphere public double Volume() { if (radius > 0) return 4.0 / 3.0 * Math.PI*radius*radius*radius; return 0.0; } } public class DemoSerialization implements Serializable { public static void main(String[] args) throws ClassNotFoundException, IOException { // 1. Write the instance of class Sphere to the "myfile.dat" file // 1.1. Create an instance sp Sphere sp = new Sphere(); // 1.2. Set the radius sp.SetR(25.5); // 1.3. Write sp to the file sp.SaveToFile("myfile.dat"); // 2. Read a previously written instance from a file // 2.1. Declare a new instance sp2 of type Sphere Sphere sp2 = new Sphere(); // 2.2. Read sp2 sp2 = sp2.ReadFromFile("myfile.dat"); // 2.3. Print the value in sp2 System.out.println("sp2.radius = " + sp2.GetR()); } }
The result of the program
sp2.radius = 25.5
⇑
Related topics
- Java I/O system. Streams. Byte streams. Character streams. Standard streams
- Work with the console. Classes InputStreamReader, PrintStream. Creating an input/output stream associated with the console. Redirecting input/output streams
- Work with files in Java. Class File. Basic working methods
- Byte streams. Classes DataInputStream, DataOutputStream, FileInputStream, FileOutputStream. Examples of using
- Examples of implementation of operations that modify text files. Classes FileReader, FileOutputStream, PrintStream
- Automatic file closure. The statement try with resources. Examples
⇑