Wednesday, January 13, 2016

Serialization in Java

ALL ABOUT SERIALIZABLE

Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in memory. This mechanism is used to persist the object.

The byte stream created is platform independent. So, the object serialized on one platform can be deserialized on a different platform.



Serializable is a marker interface. When an object has to be transferred over a network ( typically through rmi or EJB) or to persist the state of an object to a file, the object Class needs to implement Serializable interface. Implementing this interface will allow the object converted into bytestream and transfer over a network.

Which class compute serialVersionUID and Serialization mechanism ?

Everytime an object is serialized the java serialization mechanism automatically computes a hash value. ObjectStreamClass's computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is also called suid.

So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

Below two important methods helps in serializing and deserializing object.

ObjectOutputStream.writeObject() // serialize and write to the stream
ObjectInputStream.readObject() // read and deserialize to the stream


public class SerializeObject implements Serializable{

     private static final long serialVersionUID = 1L;
     int a;
     // static variable won't affect value of serialized object
     static String b;
     String c;
     public static void main(String[] args) throws IOException
{

          SerializeObject serialObject = new SerializeObject();
          FileOutputStream fo = new FileOutputStream("testSer.ser");
          ObjectOutputStream os=new ObjectOutputStream(fo);
          os.writeObject(serialObject);
         
          serialObject = new SerializeObject();
          FileInputStream fi=new FileInputStream("testSer.ser");
          ObjectInputStream oi=new ObjectInputStream(fi);
          serialObject =(SerializeObject) oi.readObject();
          System.out.println(serialObject);
          oi.close();
     }
}

If serialVersionUID is different while writing and reading, then it’ll throw below exception
Exception in thread "main" java.io.InvalidClassException: com.javaetutorials.SerializeObject; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

Object Graph
In Java it wouldn't make any sense to save the actual value of a reference variable, because the value of a Java reference has meaning only within the context of a single instance of a JVM. In other words, if you tried to restore the object in another instance of the JVM, even running on the same computer on which the object was originally serialized, the reference would be useless.

If you serialize a Dog object, the Collar will be serialized automatically.
And if the Collar class contained a reference to another object, THAT object would also be serialized, and so on.

Note : Fortunately, the Java serialization mechanism takes care of all of this. When you serialize an object, Java serialization takes care of saving that object's entire "object graph." 

That means a deep copy of everything the saved object needs to be restored.

public class ObjectGraph {
     public static void main(String[] args) throws IOException, ClassNotFoundException {
          Collar c = new Collar(3);
          Dog d = new Dog(c, 8);
         
          FileOutputStream fos = new FileOutputStream("testSerDog.ser");
          ObjectOutputStream os = new ObjectOutputStream(fos);
          os.writeObject(d);
          os.close();
          System.out.println("After Serialization ,b is "+ d.b+" before: collar size is "+ d.getCollar().getCollarSize());
         
          FileInputStream fis = new FileInputStream("testSerDog.ser");
          ObjectInputStream ois = new ObjectInputStream(fis);
          d = (Dog) ois.readObject();
          ois.close();
          System.out.println("After deserializtion b value is "+ d.b);
          System.out.println("after: collar size is "+ d.getCollar().getCollarSize());
     }
}

   /*To save Dog and restore, Collar should also need to be save...
   Without making Collar as Serializable , it throws java.io.NotSerializableException: com.javaetutorials.Collar*/

class Dog implements Serializable {
    
     private static final long serialVersionUID = -8165365370689001304L;
    
/*    >If Collar is transient and when the Dog is deserialized,          it comes back with a null Collar.
       Thus it'll throw NullPointerException...To prevent it,            make Collar as static and it'll work...
      >If Collar is static , then it'll act as class variable ,
       so need to make Collar class serializable and it doesn't          participate in Serialization...
*/

     private transient Collar theCollar;
     private int dogSize;
     // if b variable is transient i.e its state is not saved ,when deserialize it'll come back as default value...
     public transient int b=10;
     public Dog(Collar collar, int size) {
          theCollar = collar;
          dogSize = size;
     }

     public Collar getCollar() {
          return theCollar;
     }
}

/*Collar must be serializable as it has reference in Dog Object...
  To prevent Collar to be serialized, use Transient keyword...
*/

class Collar implements Serializable {

     private static final long serialVersionUID = -8706017246615683290L;
     private int collarSize;

     public Collar(int size) {
          collarSize = size;
     }

     public int getCollarSize() {
          return collarSize;
     }
}

Output :
After Serialization ,b is 10 before: collar size is 3
After deserializtion b value is 0
Exception in thread "main" java.lang.NullPointerException
          at com.javaetutorials.ObjectGraph.main(ObjectGraph.java:28)

 To prevent NullPointerException, make Collar as static variable

Output : 
After Serialization ,b is 10 before: collar size is 3
After deserializtion b value is 0
after: collar size is 3

Another way to serialize objects :
·        Externalization implements Serialization
·        XML Serialization
·        Write an object's content directly via either the ObjectOutputStream or the DataOutputStream.

What happens if an object is serializable but it includes a reference to a non-serializable object?


Exception in thread "main" java.io.NotSerializableException: com.javaetutorials.Collar

Sunday, January 10, 2016

Bubble Sort, Selection Sort and Insertion Sort

Sorting Algorithms with complexity o(n^2)

Bubble Sort

public class BubbleSort {
      public static void main(String[] args) {
            int num[] = new int[] { 20, 13, 23, 19, 29, 1 };
            for (int i = 0; i <= (num.length) - 2; i++) {
                  for (int j = 0; j <= (num.length) - 2 - i; j++) {
                        if (num[j] > num[j + 1]) {
                              int temp = num[j];
                              num[j] = num[j + 1];
                              num[j + 1] = temp;
                        }
                  }
            }
            StringBuffer sb = new StringBuffer();
            for (int i : num) {
                  sb.append(i).append(" ");
            }
            System.out.println(sb.toString());
      }
}

Selection Sort

package com.javaetutorials;

/*Finding the smallest element and swapping with the first element ,
 thus fixing the starting position to the last position*/

public class SelectionSort {
      public static void main(String[] args) {
            int num[] = new int[] { 20, 13, 23, 19, 29, 1 };
            for (int i = 0; i <= num.length - 2; i++) {
                  // Min index is the first element of unsorted list
                  int min = i;

                  /*
                   * Find minimum element index in Unsorted List. Update the Minimum
                   * element index.
                   */
                  for (int j = i + 1; j <= num.length - 1; j++) {
                        if (num[j] < num[min])
                              min = j;
                  }
                  int temp = num[min];
                  num[min] = num[i];
                  num[i] = temp;
            }
            for (int arr : num)
                  System.out.print(arr + ",");
      }
}

Insertion Sort

package com.javaetutorials;

public class InsertionSort {
          public static void main(String[] args) {
                   int num[] = new int[] { 20, 13, 23, 19, 29, 1 }, i, j, key;
                   for (i = 1; i <= num.length - 1; i++) {
                             key = num[i];
                             j = i - 1;
                             while (j >= 0 && key < num[j]) {
                                      num[j + 1] = num[j];
                                      j--;
                             }
                             num[j + 1] = key;
                   }
                   for (int arr : num)
                             System.out.print(arr + ",");
          }
}

< in highlighted portion making it Stable Sort whereas <= will move the element to left and thus making it Unstable Sort.


Saturday, January 9, 2016

How Garbage Collection works in Java

Garbage Collection in Java

Garbage collection is a mechanism to reclaim heap memory occupied by those objects which are not being used by any of the live threads of our program. JVM periodically runs a process called Garbage Collector which checks which objects are being used and which are not, and reclaims memories from unused objects and gives it back to the heap memory for future use. Apart from reclaiming memory from unused objects, garbage collector also ensures that objects having live references exist and thus avoids the situation called dangling reference

An object become eligible for garbage collection in the following scenarios:
  •      If the object is assigned a null value like 'object = null', then it becomes eligible for garbage collection.
  •      If a parent object A contains a reference of object B, and if the object A is set to null, then object B also becomes eligible for garbage collection.
  •     If the object is created inside a block and the program control goes out of the scope of the block, then the object becomes eligible for garbage collection.







Here green color represents referenced objects and red color indicates un-referenced ones. Upon moving to survivor space 1, referenced objects get their reference count incremented by one.





In this way, objects continue to get promoted to the old generation because of minor garbage collections. At the end, JVM runs a major garbage collector on the old generation which claims the memories occupied by unused objects and returns it back to the heap memory.