Monday, February 1, 2016

My Technical memories: memory - 4

I had been busy, actually very very busy with some technical preparations on SOA. I kind of forgot to look into the past. But like a ghost past pops up at one or the other occasion. So it happened that I had to look into Serialization for some issue and here I see the Ghost of past reminding me of interesting issue about static and serialization. Static data is not serialized. Oh! I forgot to tell you, I am talking about Java Object Serialization. So here is a small example to show from my Java memories…
I created an Employee class which implements Serializable. This class object is to be Serialized.

package test.domain;
import java.io.Serializable;

public class Employee implements Serializable{
    private int empId;
    private String empName;
    private double salary;
    public static final int branchCode=3;
    public static int count;

    /*public Employee() {
        count++;
        empId=count;
    }*/

    public Employee(String empName, double salary) {
        count++;
        empId=count;
        this.empName = empName;
        this.salary = salary;
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public static int getCount() {
        return count;
    }

    public static void setCount(int count) {
        Employee.count = count;
    }

    public String toString(){
        return "count : "+count+
        "  Employee Id : "+empId+
        "  Branch Code : "+branchCode+
        "  Employee Name : "+empName+
        "  salary : "+salary;
    }
  }

Then I created a class which can serialize the objects of Employee class. I named this class as PersistEmployee.

package teststatic;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import test.domain.Employee;

public class PersistEmployee {

    public static void main(String[] args) {
        Employee emp;
         try (FileOutputStream fos = new FileOutputStream("d:\\emp.dat");
              ObjectOutputStream out = new ObjectOutputStream(fos)) {
                emp=new Employee("John",120000);
                out.writeObject(emp);
                emp=new Employee("Tim",140000);
                out.writeObject(emp);
         }catch(IOException e){
             System.out.println("Input Output Error...");
         }

        /* Employee e;
         try (FileInputStream fis = new FileInputStream("d:\\emp.dat");
                ObjectInputStream in = new ObjectInputStream(fis)) {
                e = (Employee)in.readObject();
                System.out.println (e);
                e = (Employee)in.readObject();
                System.out.println (e);
        } catch (ClassNotFoundException | IOException i) {
            System.out.println("Exception reading in Portfolio: " + i);
        }*/
    }
}

When I run this class, it serializes two objects of Employee class, static variable will be incremented with every constructor call. After these two objects are created value of count will be 2, branchCode is static final and will always hold value 3.  I am using static and static final variables in the Employee class. The code will show how JVM deals with static and static final during serialization and deserialization.

I created another class ReadEmployee where deserialization is taking place for Employee objects.

package teststatic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import test.domain.Employee;

public class ReadEmployee {

     public static void main(String[] args) {
        Employee e;
    
        try (FileInputStream fis = new FileInputStream("d:\\emp.dat");
                ObjectInputStream in = new ObjectInputStream(fis)) {
                e = (Employee)in.readObject();
                System.out.println (e);
                e = (Employee)in.readObject();
                System.out.println (e);
        } catch (ClassNotFoundException | IOException i) {
            System.out.println("Exception reading in Portfolio: " + i);
        }
    }
}

Now when I run ReadEmployee it brings this result for me.

run:
count : 0  Employee Id : 1  Branch Code : 3  Employee Name : John  salary : 120000.0
count : 0  Employee Id : 2  Branch Code : 3  Employee Name : Tim  salary : 140000.0
BUILD SUCCESSFUL (total time: 2 seconds)

I can see that static variable value is zero, static variable is not persisted, branchCode is also not persisted, but it prints value 3 because it is static final variable. An interesting part will be be if you uncomment the read code from PersistEmployee and run it. In this case both serialization and deserialization happens in the same class and hence you will find an interesting difference in the outcome. Here it is:

run:
count : 2  Employee Id : 1  Branch Code : 3  Employee Name : John  salary : 120000.0
count : 2  Employee Id : 2  Branch Code : 3  Employee Name : Tim  salary : 140000.0
BUILD SUCCESSFUL (total time: 2 seconds)

Can you figure out why count shows value 2 and not zero?