Deep analysis of serialization _java in Java programming

Source: Internet
Author: User
Tags serialization

Java provides a mechanism called serialization, which persists Java objects in an ordered format or byte sequence, containing the object's data, the object's type, and the data type stored in the object.

So, if we have serialized an object, it can be read and deserialized by the type and other information of the object, and eventually the object's prototype is obtained.

The ObjectInputStream and ObjectOutputStream objects are high-level stream objects that contain methods for serialization and deserialization.

ObjectOutputStream has a number of methods for serializing objects, most commonly:

private void WriteObject (ObjectOutputStream os) throws IOException
 {
   
 }

Similar ObjectInputStream provide the following methods:

 private void ReadObject (ObjectInputStream is) throws IOException, ClassNotFoundException
 {
   
 }

So where does it need to be serialized? Serialization is usually used when you need to transfer data over a network, or to save objects to a file. The data here is the object, not the text.

The problem now is that our network architecture and hard disk can only recognize binaries and bytes, but not Java objects.

Serialization is the translation of value/states in Java objects into bytes to be transmitted or saved over the network. In addition, deserialization is done by reading the byte code and translating it back into the Java object.

Serialversionuid concept

Serialversionuid is used to ensure that the same object (which is used in serialization) can be loaded in the deserialization process. Serialversionuid is the version control used for the object. You can refer to Serialversionuid in Java serialization for more information.

For serialization:

The steps are as follows:

Let's take a look:

Create Employee.java in Src->org.arpit.javapostsforlearning

1.employee.java

Package org.arpit.javapostsforlearning;
Import java.io.Serializable;
public class Employee implements serializable{
 
 int employeeId;
 String EmployeeName;
 String Department;
  
 public int Getemployeeid () {return
  employeeId;
 }
 public void Setemployeeid (int employeeId) {
  This.employeeid = employeeId;
 }
 Public String Getemployeename () {return
  employeename;
 }
 public void Setemployeename (String employeename) {
  this.employeename = EmployeeName;
 }
 Public String getdepartment () {return
  department;
 }
 public void Setdepartment (String department) {
  this.department = department;
 }
}

As you can see, if you need to serialize any class, then you have to implement the Serializable interface, which is the markup interface (marker interface).


The markup interface in Java (marker interface) is an interface without any fields or methods, simply speaking, the empty interface in Java is called the Tag interface (marker interface)

2.serializemain.java

Package org.arpit.javapostsforlearning;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.ObjectOutputStream;
 public class Serializemain {
 
 /**
 * @author arpit Mandliya
 *
 /public static void main (string[] args) {
   
    employee emp = new Employee ();
 Emp.setemployeeid ();
 Emp.setemployeename ("Arpit");
 Emp.setdepartment ("CS");
 Try
 {
 FileOutputStream fileout = new FileOutputStream ("Employee.ser");
 ObjectOutputStream OutStream = new ObjectOutputStream (fileout);
 Outstream.writeobject (EMP);
 Outstream.close ();
 Fileout.close ();
 } catch (IOException i)
 {
 i.printstacktrace ();
 }
 }
}

   

For deserialization:
Steps are

In the package src->org.arpit.javapostsforlearning, create the Deserializemain.java
3.deserializemain.java

 package org.arpit.javapostsforlearning; import java.io.IOException; import
 
Java.io.ObjectInputStream; public class Deserializemain {/** * @author arpit Mandliya */public static void main (string[] args) {Employee em
  p = null;
   try {fileinputstream Filein =new fileinputstream ("Employee.ser");
   ObjectInputStream in = new ObjectInputStream (Filein);
   EMP = (Employee) in.readobject ();
   In.close ();
  Filein.close ();
   }catch (IOException i) {i.printstacktrace ();
  Return
   }catch (classnotfoundexception c) {System.out.println ("Employee class not Found");
   C.printstacktrace ();
  Return
  } System.out.println ("Deserialized Employee ...");
  SYSTEM.OUT.PRINTLN ("EMP ID:" + emp.getemployeeid ());
  System.out.println ("Name:" + emp.getemployeename ());
 System.out.println ("Department:" + emp.getdepartment ()); }
}


4. Run:
Run Serializemain.java first, then run Deserializemain.java, and you will get the following results:

Deserialized Employee ...
EMP id:101
name:arpit
Department:cs

In this way, we serialized an employee object and deserialized it. This looks and is simple, but if it contains an object reference, inheritance, then the situation becomes complicated. Let's take a look at the example one after another to see how serialization can be achieved in various situations.

Case 1-What if the object references another object

We've seen the simplest example of serialization, and now look at how to handle situations where objects are referenced in other objects. How do we serialize? Will the referenced object also be serialized? Yes, you don't need to explicitly serialize the referenced object. When you serialize any object, if it contains a reference object, then Java serialization automatically serializes the entire object graph of that object. For example, employee now references an address object, and address also references other objects (for example, home), so when you serialize an employee object, all other referenced objects, such as address and home, are automatically serialized. Let's create the address class, and the object that it address as a reference, is added to the employee class.

Employee.java:

Package org.arpit.javapostsforlearning;
Import java.io.Serializable;
 
public class Employee implements serializable{
 
 int employeeId;
 String EmployeeName;
 String Department;
 Address address;
 
 public int Getemployeeid () {return
 employeeId;
 }
 public void Setemployeeid (int employeeId) {
 This.employeeid = employeeId;
 }
 Public String Getemployeename () {return
 employeename;
 }
 public void Setemployeename (String employeename) {
 this.employeename = EmployeeName;
 }
 Public String getdepartment () {return
 department;
 }
 public void Setdepartment (String department) {
 this.department = department;
 }
 Public Address getaddress () {return address
 ;
 }
 public void setaddress [address] {
 this.address = address;
 }
}

In the org.arpit.javapostsforlearning package, create the Address.java
Address.java:

Package org.arpit.javapostsforlearning;
public class Address {
 
 int homeno;
 String Street;
 String City;
 public address (int Homeno, String Street, String city) {
 super ();
 This.homeno = Homeno;
 This.street = Street;
 this.city = city;
 }
 public int Gethomeno () {return
 Homeno;
 }
 public void Sethomeno (int homeno) {
 This.homeno = Homeno;
 }
 Public String Getstreet () {return street
 ;
 }
 public void Setstreet (String street) {
 this.street = Street;
 }
 Public String getcity () {return city
 ;
 }
 public void Setcity (String city) {
 this.city = city;
 }
}

In the package org.arpit.javapostsforlearning, create the Serializedeserializemain.java
Serializedeserializemain.java:

Package org.arpit.javapostsforlearning;
Import Java.io.FileInputStream;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.ObjectInputStream;
 
Import Java.io.ObjectOutputStream; public class Serializedeserializemain {/** * @author arpit Mandliya */public static void main (string[] args) {Em
 Ployee emp = new Employee ();
 Emp.setemployeeid (101);
 Emp.setemployeename ("Arpit");
 Emp.setdepartment ("CS");
 Address Address=new address (the "MG Road", "Pune");
 Emp.setaddress (address);
 Serialize try {fileoutputstream fileout = new FileOutputStream ("Employee.ser");
 ObjectOutputStream OutStream = new ObjectOutputStream (fileout);
 Outstream.writeobject (EMP);
 Outstream.close ();
 Fileout.close ();
 }catch (IOException i) {i.printstacktrace ();
 //deserialize emp = null;
 try {fileinputstream Filein =new fileinputstream ("Employee.ser");
 ObjectInputStream in = new ObjectInputStream (Filein);
 EMP = (Employee) in.readobject ();
 In.close (); Filein.closE ();
 }catch (IOException i) {i.printstacktrace ();
 Return
 }catch (classnotfoundexception c) {System.out.println ("Employee class not Found");
 C.printstacktrace ();
 Return
 } System.out.println ("Deserialized Employee ...");
 SYSTEM.OUT.PRINTLN ("EMP ID:" + emp.getemployeeid ());
 System.out.println ("Name:" + emp.getemployeename ());
 System.out.println ("Department:" + emp.getdepartment ());
 Address=emp.getaddress ();
 System.out.println ("City:" +address.getcity ());
 }
}

Run it:
When you run Serializedeserializemain.java. You will get the result:

Java.io.NotSerializableException:org.arpit.javapostsforlearning.Address at
 Java.io.ObjectOutputStream.writeObject0 (Unknown Source) at
 Java.io.ObjectOutputStream.defaultWriteFields ( Unknown source) at
 Java.io.ObjectOutputStream.writeSerialData (Unknown source)
 at Java.io.ObjectOutputStream.writeOrdinaryObject (Unknown Source) at
 java.io.ObjectOutputStream.writeObject0 ( Unknown source) at
 Java.io.ObjectOutputStream.writeObject (Unknown source) 

We will explain what went wrong. I forgot to say that the address class must also be serializable. Then the address class must inherit the Serialzable interface.

Address.java:

Import java.io.Serializable;
 
Public class address implements serializable{
 
 int homeno;
 String Street;
 String City;
 public address (int Homeno, String Street, String city) {
 super ();
 This.homeno = Homeno;
 This.street = Street;
 this.city = city;
 }
 public int Gethomeno () {return
 Homeno;
 }
 public void Sethomeno (int homeno) {
 This.homeno = Homeno;
 }
 Public String Getstreet () {return street
 ;
 }
 public void Setstreet (String street) {
 this.street = Street;
 }
 Public String getcity () {return city
 ;
 }
 public void Setcity (String city) {
 this.city = city;
 }
}

Run again:
When you run Serializedeserializemain.java again. You can get the following results

Deserialized Employee ...
EMP id:101
name:arpit
department:cs City
:P une

Case 2: If we cannot access the source code of the referenced object (for example, you cannot access the source of the address class above)

If we don't have access to the address class, how do we implement the serializable interface in the address class? Is there another way to achieve it? Yes, you can create another class, inherit the address, and let it inherit the serializable interface, but for the following scenario, the scenario fails:

If the reference class is defined as final
If a reference class refers to another object that is not serializable

So, how do we serialize the Employee object? The solution is to mark the transient. If you don't need to serialize any of the fields, just mark it as transient.

Transient address
In the employee class, after you mark the address as transient, run the program. You will get nullpointerexception, because the address reference will be null during deserialization.


Case 3-What if I still need to save the state of the referenced object? (For example, address object)

If you mark the address as transient during deserialization, it will return a null result. But if you still need to preserve its state, you need to serialize the address object. Java serialization provides a mechanism that if you have a private method for a particular signature, they are invoked during serialization and deserialization, so we'll rewrite the WriteObject and ReadObject methods of the Employee class, They are then invoked during the process of serialization/deserialization of the Employee object.

Employee.java:

Package org.arpit.javapostsforlearning;
Import java.io.IOException;
Import Java.io.ObjectInputStream;
Import Java.io.ObjectOutputStream;
 
Import java.io.Serializable;
 public class Employee implements serializable{int employeeId;
 String EmployeeName;
 String Department;
 
 transient address;
 public int Getemployeeid () {return employeeId;
 The public void Setemployeeid (int employeeId) {This.employeeid = EmployeeId;
 Public String Getemployeename () {return employeename;
 } public void Setemployeename (String employeename) {this.employeename = EmployeeName;
 Public String getdepartment () {return department;
 } public void Setdepartment (String department) {this.department = Department;
 Public Address getaddress () {return address;
 public void setaddress (address) {this.address = address; } private void WriteObject (ObjectOutputStream os) throws IOException, ClassNotFoundException {try {os.defaultwrite
 Object (); Os.writeint (address.Gethomeno ());
 Os.writeobject (Address.getstreet ());
 Os.writeobject (Address.getcity ());
 catch (Exception e) {e.printstacktrace ();} } private void ReadObject (ObjectInputStream is) throws IOException, ClassNotFoundException {try {is.defaultreadobj
 ECT ();
 int Homeno=is.readint ();
 String street= (String) is.readobject ();
 String city= (String) is.readobject ();
 
 Address=new address (homeno,street,city);
 catch (Exception e) {e.printstacktrace ();}
 }
}

Another thing to keep in mind is that the order in which ObjectInputStream reads data is the same as the order in which ObjectOutputStream writes the data.

Creating Address.java in Package org.arpit.javapostsforlearning
Address.java:

Package org.arpit.javapostsforlearning;
Import java.io.Serializable;
 
public class Address {
 
 int homeno;
 String Street;
 String City;
 
 
 public address (int Homeno, String Street, String city) {
 super ();
 This.homeno = Homeno;
 This.street = Street;
 this.city = city;
 }
 public int Gethomeno () {return
 Homeno;
 }
 public void Sethomeno (int homeno) {
 This.homeno = Homeno;
 }
 Public String Getstreet () {return street
 ;
 }
 public void Setstreet (String street) {
 this.street = Street;
 }
 Public String getcity () {return city
 ;
 }
 public void Setcity (String city) {
 this.city = city;
 }
}

Creating Serializedeserializemain.java in Package org.arpit.javapostsforlearning
Serializedeserializemain.java:

Package org.arpit.javapostsforlearning;
Import Java.io.FileInputStream;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.ObjectInputStream;
 
Import Java.io.ObjectOutputStream; public class Serializedeserializemain {/** * @author arpit Mandliya */public static void main (string[] args) {Em
 Ployee emp = new Employee ();
 Emp.setemployeeid (101);
 Emp.setemployeename ("Arpit");
 Emp.setdepartment ("CS");
 Address Address=new address (the "MG Road", "Pune");
 Emp.setaddress (address);
 Serialize try {fileoutputstream fileout = new FileOutputStream ("Employee.ser");
 ObjectOutputStream OutStream = new ObjectOutputStream (fileout);
 Outstream.writeobject (EMP);
 Outstream.close ();
 Fileout.close ();
 }catch (IOException i) {i.printstacktrace ();
 //deserialize emp = null;
 try {fileinputstream Filein =new fileinputstream ("Employee.ser");
 ObjectInputStream in = new ObjectInputStream (Filein);
 EMP = (Employee) in.readobject ();
 In.close (); Filein.closE ();
 }catch (IOException i) {i.printstacktrace ();
 Return
 }catch (classnotfoundexception c) {System.out.println ("Employee class not Found");
 C.printstacktrace ();
 Return
 } System.out.println ("Deserialized Employee ...");
 SYSTEM.OUT.PRINTLN ("EMP ID:" + emp.getemployeeid ());
 System.out.println ("Name:" + emp.getemployeename ());
 System.out.println ("Department:" + emp.getdepartment ());
 Address=emp.getaddress ();
 System.out.println ("City:" +address.getcity ());
 }
}

Run:
When you run Serializedeserializemain.java. You will get the following results:

Deserialized Employee ...
EMP id:101
name:arpit
department:cs City
:P une

Now we get the state of the address object, just as it was before it was serialized.

Inheritance in serialization:

Now let's see how inheritance affects serialization. This leads to a number of examples, regardless of whether the parent class is serializable. If the parent class is serializable, how do we handle it and how does it work. Let's take a look at the examples.

We will create a Person.java as the parent class for employee.

Case 4: If the parent class is serializable

If the parent class is serializable, then all the inherited classes will be serializable.

Case 5: What if the parent class is not serializable?

If the parent class is not serializable, then our approach will be very different.

If the parent class is not serializable, then it must not have a parameter constructor.

Person.java

Package org.arpit.javapostsforlearning;
public class Person {
 
 String name= "Default";
 String nationality;
 
 Public person ()
 {
 System.out.println ("Person:constructor");
 }
 
 Public person (string name, String nationality) {
 super ();
 this.name = name;
 This.nationality = nationality;
 }
 
 Public String GetName () {return
 name;
 }
 
 public void SetName (String name) {
 this.name = name;
 }
 
 Public String getnationality () {return
 nationality;
 }
 
 public void Setnationality (String nationality) {
 this.nationality = nationality;
 }
 
}

Creating Employee.java in Package org.arpit.javapostsforlearning
Employee.java:


Package org.arpit.javapostsforlearning;
Import java.io.Serializable;
 
public class Employee extends person implements serializable{
 
 int employeeId;
 String Department;
 
 Public Employee (int employeeid,string name,string department,string Nationality)
 {
 super (name,nationality);
 This.employeeid=employeeid;
 this.department=department;
 System.out.println ("Employee:constructor");
 }
 
 public int Getemployeeid () {return
 employeeId;
 }
 public void Setemployeeid (int employeeId) {
 This.employeeid = employeeId;
 }
 
 Public String getdepartment () {return
 department;
 }
 public void Setdepartment (String department) {
 this.department = department;
 }
}

Create Serializedeserializemain.java in Org.arpit.javapostsforlearning package

Serializedeserializemain.java:


Package org.arpit.javapostsforlearning;
Import Java.io.FileInputStream;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.ObjectInputStream;
 
Import Java.io.ObjectOutputStream;
 
 public class Serializedeserializemain {/** * @author arpit Mandliya */public static void main (string[] args) {
 Serialize Employee EMP = new Employee ("Arpit", "CS", "Indian");
 System.out.println ("before serializing");
 SYSTEM.OUT.PRINTLN ("EMP ID:" + emp.getemployeeid ());
 System.out.println ("Name:" + emp.getname ());
 System.out.println ("Department:" + emp.getdepartment ());
 System.out.println ("Nationality:" + emp.getnationality ());
 System.out.println ("************");
 System.out.println ("serializing");
 try {fileoutputstream fileout = new FileOutputStream ("Employee.ser");
 ObjectOutputStream OutStream = new ObjectOutputStream (fileout);
 Outstream.writeobject (EMP);
 Outstream.close ();
 Fileout.close ();
 }catch (IOException i) {i.printstacktrace (); }//desErialize System.out.println ("************");
 SYSTEM.OUT.PRINTLN ("deserializing");
 EMP = NULL;
 try {fileinputstream Filein =new fileinputstream ("Employee.ser");
 ObjectInputStream in = new ObjectInputStream (Filein);
 EMP = (Employee) in.readobject ();
 In.close ();
 Filein.close ();
 }catch (IOException i) {i.printstacktrace ();
 Return
 }catch (classnotfoundexception c) {System.out.println ("Employee class not Found");
 C.printstacktrace ();
 Return
 } System.out.println ("after serializing");
 SYSTEM.OUT.PRINTLN ("EMP ID:" + emp.getemployeeid ());
 System.out.println ("Name:" + emp.getname ());
 System.out.println ("Department:" + emp.getdepartment ());
 System.out.println ("Nationality:" + emp.getnationality ());
 }
}

Run:

When you run Serializedeserializemain.java, you get the following output, and if the parent class is serializable, all instance variable values that inherit from the parent class are initialized in the deserialization process by calling the non-serialization constructor. Here name inherits from person, so during deserialization, name will be initialized to the default value.


Case 6-If the parent class is serializable, but you do not need to inherit the class for serializable

If you do not want the inheriting class to be serializable, then you need to implement the WriteObject () and ReadObject () methods, and you need to throw notserializableexception exceptions.

Case 7-Can I serialize a static variable?

No. Because static variables are class-level, not object-level, you cannot serialize static variables when you serialize an object.


Summary:

    • Serialization is the process of converting a Java object's values/states into bytes and transferring or saving it in a network. In addition, deserialization is the process of translating the bytecode into the corresponding object.
    • The advantage of serialization is that the JVM is independent, that is, an object can be serialized in one platform, and then deserialized on another different platform.
    • If you need to serialize any object, you must implement the tag interface serializable.
    • The markup interface in Java (Marker interface) is an interface without a field or method, or, to put it simply, an empty interface
    • Serialversionuid is used to ensure that the same object (which is used in serialization) can be loaded in the deserialization process. Serialversionuid is the version control used for the object.
    • When you need to serialize any object that contains a reference object, Java automatically serializes the entire object graph of that object.
    • If you don't want to serialize a field, you can mark it as a trasient
    • If the parent class is serializable, then its inheriting class will also be serializable.
    • If the parent class is not serializable, all instance variable values inherited from the parent class will be initialized by calling the non serializable constructor during deserialization.
    • If you want subclasses to be serializable, then you need to implement the WriteObject () and ReadObject () methods and throw notserializableexception exceptions in both methods
    • You cannot serialize static variables.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.