Serialization understanding


Depth understanding of serialization 



Serialization process is implemented by ObjectInputStream and ObjectOutputStream, so all we need is a wrapper over them to either save it to file or send it over the network. Let’s see a simple Serialization example.

Employee.java

package com.kartik;

import java.io.Serializable;

public class Employee implements Serializable{

    private String name;

    private int id;

    transient private int salary;

    transient private String password;

    @Override

    public String toString(){

        return "Employee{name="+name+",id="+id+",salary="+salary+",password="+password+"}";

    }

    //getter and setter methods

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public int getSalary() {

        return salary;

    }

    public void setSalary(int salary) {

        this.salary = salary;

    }

 /**

  * @return the password

  */

 public String getPassword() {

  return password;

 }

 /**

  * @param password the password to set

  */

 public void setPassword(String password) {

  this.password = password;

 }

}



Notice that it’s a simple java bean with some properties and getter-setter methods. If you want an object property to be not serialized to stream, you can use transient keyword like I have done with salary variable.

Now suppose we want to write our objects to file and then deserialize it from the same file. So we need utility methods that will use ObjectInputStream and ObjectOutputStream for serialization purposes.



SerializationUtil

package com.kartik;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;



import java.io.ObjectOutputStream;

/**

 * A simple class with generic serialize and deserialize method implementations

 *

 * @author Kartik

 *

 */

public class SerializationUtil {

    // deserialize to Object from given file

    public static Object deserialize(String fileName) throws IOException,

            ClassNotFoundException {

        FileInputStream fis = new FileInputStream(fileName);

        ObjectInputStream ois = new ObjectInputStream(fis);

        Object obj = ois.readObject();

        ois.close();

        return obj;

    }

    // serialize the given object and save it to file

    public static void serialize(Object obj, String fileName)

            throws IOException {

        FileOutputStream fos = new FileOutputStream(fileName);

        ObjectOutputStream oos = new ObjectOutputStream(fos);

        oos.writeObject(obj);



        fos.close();

    }

}

Notice that the method arguments work with Object that is the base class of any java object. It’s written in this way to be generic in nature.

Now let’s write a test program to see Java Serialization in action.


SerializationTest

package com.ser;



import java.io.IOException;



public class SerializationTest {

   

    public static void main(String[] args) {

        String fileName="employee.txt";

        Employee emp = new Employee();

        emp.setId(100);

        emp.setName("kartik");

        emp.setSalary(5000);

        emp.setPassword("kartik");

       

        //serialize to file

        try {

            SerializationUtil.serialize(emp, fileName);

        } catch (IOException e) {

            e.printStackTrace();

            return;

        }

       

        Employee empNew = null;

        try {

            empNew = (Employee) SerializationUtil.deserialize(fileName);

        } catch (ClassNotFoundException | IOException e) {

            e.printStackTrace();

        }

       

        System.out.println("emp Object::"+emp);

        System.out.println("empNew Object::"+empNew);

    }





}

When we run above test program, we get following output.

emp Object::Employee{name=kartik,id=100,salary=5000,password=kartik}

empNew Object::Employee{name=kartik,id=100,salary=0,password=null}





Since salary and password are  transient variables, it’s value was not saved to file and hence not retrieved in the new object. Similarly static variable values are also not serialized since they belongs to class and not object.





Class Refactoring with Serialization and serialVersionUID
Java Serialization permits some changes in the java class if they can be ignored. Some of the changes in class that will not affect the deserialization process are:

·                  Adding new variables to the class

·                  Changing the variables from transient to non-transient, for serialization it’s like having a new field.

·                  Changing the variable from static to non-static, for serialization it’s like having a new field.

But for all these changes to work, the java class should have serialVersionUID defined for the class. Let’s write a test class just for deserialization of the already serialized file from previous test class.

DeserializationTest.java



package com.kartik;



import java.io.IOException;



public class DeserializationTest {



    public static void main(String[] args) {



        String fileName="employee.ser";

        Employee empNew = null;

         

        try {

            empNew = (Employee) SerializationUtil.deserialize(fileName);

        } catch (ClassNotFoundException | IOException e) {

            e.printStackTrace();

        }

         

        System.out.println("empNew Object::"+empNew);

         

    }



}

Now uncomment the “password” variable and it’s getter-setter methods from Employee class and run it. You will get below exception;



java.io.InvalidClassException: com.kartik.Employee; local class incompatible: stream classdesc serialVersionUID = -6470090944414208496, local class serialVersionUID = -6234198221249432383

    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:604)

    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601)

    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)

    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)

    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)

    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)

    at com.kartik.SerializationUtil.deserialize(SerializationUtil.java:22)

    at com.kartik.DeserializationTest.main(DeserializationTest.java:13)

empNew Object::null

The reason is clear that serialVersionUID of the previous class and new class are different. Actually if the class doesn’t define serialVersionUID, it’s getting calculated automatically and assigned to the class. Java uses class variables, methods, class name, package etc to generate this unique long number. If you are working with any IDE, you will automatically get a warning that “The serializable class Employee does not declare a static final serialVersionUID field of type long”.

We can use java utility “serialver” to generate the class serialVersionUID, for Employee class we can run it with below command.

1

SerializationExample/bin$serialver -classpath . com.journaldev.serialization.Employee

Note that it’s not required that the serial version is generated from this program itself, we can assign this value as we want. It just need to be there to let deserialization process know that the new class is the new version of the same class and should be deserialized of possible.

For example, uncomment only the serialVersionUID field from the Employee class and run SerializationTestprogram. Now uncomment the password field from Employee class and run the DeserializationTestprogram and you will see that the object stream is deserialized successfully because the change in Employee class is compatible with serialization process.

Java Externalizable Interface
If you notice the serialization process, it’s done automatically. Sometimes we want to obscure the object data to maintain it’s integrity. We can do this by implementing java.io.Externalizable interface and provide implementation of writeExternal() and readExternal() methods to be used in serialization process.

Person.java



package com.journaldev.externalization;



import java.io.Externalizable;

import java.io.IOException;

import java.io.ObjectInput;

import java.io.ObjectOutput;



public class Person implements Externalizable{



    private int id;

    private String name;

    private String gender;

     

    @Override

    public void writeExternal(ObjectOutput out) throws IOException {

        out.writeInt(id);

        out.writeObject(name+"xyz");

        out.writeObject("abc"+gender);

    }



    @Override

    public void readExternal(ObjectInput in) throws IOException,

            ClassNotFoundException {

        id=in.readInt();

        //read in the same order as written

        name=(String) in.readObject();

        if(!name.endsWith("xyz")) throw new IOException("corrupted data");

        name=name.substring(0, name.length()-3);

        gender=(String) in.readObject();

        if(!gender.startsWith("abc")) throw new IOException("corrupted data");

        gender=gender.substring(3);

    }



    @Override

    public String toString(){

        return "Person{id="+id+",name="+name+",gender="+gender+"}";

    }

    public int getId() {

        return id;

    }



    public void setId(int id) {

        this.id = id;

    }



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public String getGender() {

        return gender;

    }



    public void setGender(String gender) {

        this.gender = gender;

    }



}

Notice that I have changed the field values before converting it to Stream and then while reading reversed the changes. In this way, we can maintain data integrity of some sorts. We can throw exception if after reading the stream data, the integrity checks fail. Let’s write a test program to see it in action.

 ExternalizationTest.java



package com.journaldev.externalization;



import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;



public class ExternalizationTest {



    public static void main(String[] args) {

         

        String fileName = "person.ser";

        Person person = new Person();

        person.setId(1);

        person.setName("Kartik");

        person.setGender("Male");

         

        try {

            FileOutputStream fos = new FileOutputStream(fileName);

            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(person);

            oos.close();

        } catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

         

        FileInputStream fis;

        try {

            fis = new FileInputStream(fileName);

            ObjectInputStream ois = new ObjectInputStream(fis);

            Person p = (Person)ois.readObject();

            ois.close();

            System.out.println("Person Object Read="+p);

        } catch (IOException | ClassNotFoundException e) {

            e.printStackTrace();

        }

         

    }



}

When we run above program, we get following output.

1

Person Object Read=Person{id=1,name=Kartik,gender=Male}

So which one is better to be used for serialization purpose. Actually it’s better to use Serializable interface and by the time we reach at the end of article, you will know why.

Java Serialization Methods
We have seen that java serialization is automatic and all we need is implementing Serializable interface. The implementation is present in the ObjectInputStream and ObjectOutputStream classes. But what if we want to change the way we are saving data, for example we have some sensitive information in the object and before saving/retrieving we want to encrypt/decrypt it. That’s why there are four methods that we can provide in the class to change the serialization behavior.

If these methods are present in the class, they are used for serialization purposes.

1.               readObject(ObjectInputStream ois): If this method is present in the class, ObjectInputStream readObject() method will use this method for reading the object from stream.

2.               writeObject(ObjectOutputStream oos): If this method is present in the class, ObjectOutputStream writeObject() method will use this method for writing the object to stream. One of the common usage is to obscure the object variables to maintain data integrity.

3.               Object writeReplace(): If this method is present, then after serialization process this method is called and the object returned is serialized to the stream.

4.               Object readResolve(): If this method is present, then after deserialization process, this method is called to return the final object to the caller program. One of the usage of this method is to implement Singleton pattern with Serialized classes. Read more at Serialization and Singleton.

Usually while implementing above methods, it’s kept as private so that subclasses can’t override them. They are meant for serialization purpose only and keeping them private avoids any security issue.

Serialization with Inheritance
Sometimes we need to extend a class that doesn’t implement Serializable interface. If we rely on the automatic serialization behavior and the superclass has some state, then they will not be converted to stream and hence not retrieved later on.

This is one place, where readObject() and writeObject() methods really help. By providing their implementation, we can save the super class state to the stream and then retrieve it later on. Let’s see this in action.

SuperClass.java



package com.journaldev.serialization.inheritance;



public class SuperClass {



    private int id;

    private String value;

     

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getValue() {

        return value;

    }

    public void setValue(String value) {

        this.value = value;

    }

     

     

}

SuperClass is a simple java bean but it’s not implementing Serializable interface.

SubClass.java



package com.journaldev.serialization.inheritance;



import java.io.IOException;

import java.io.InvalidObjectException;

import java.io.ObjectInputStream;

import java.io.ObjectInputValidation;

import java.io.ObjectOutputStream;

import java.io.Serializable;



public class SubClass extends SuperClass implements Serializable, ObjectInputValidation{



    private static final long serialVersionUID = -1322322139926390329L;



    private String name;



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }

     

    @Override

    public String toString(){

        return "SubClass{id="+getId()+",value="+getValue()+",name="+getName()+"}";

    }

     

    //adding helper method for serialization to save/initialize super class state

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException{

        ois.defaultReadObject();

         

        //notice the order of read and write should be same

        setId(ois.readInt());

        setValue((String) ois.readObject());

         

    }

     

    private void writeObject(ObjectOutputStream oos) throws IOException{

        oos.defaultWriteObject();

         

        oos.writeInt(getId());

        oos.writeObject(getValue());

    }



    @Override

    public void validateObject() throws InvalidObjectException {

        //validate the object here

        if(name == null || "".equals(name)) throw new InvalidObjectException("name can't be null or empty");

        if(getId() <=0) throw new InvalidObjectException("ID can't be negative or zero");

    }

}


Notice that order of writing and reading the extra data to the stream should be same. We can put some logic in reading and writing data to make it secure.

Also notice that the class is implementing ObjectInputValidation interface. By implementing validateObject()method, we can put some business validations to make sure that the data integrity is not harmed.

Let’s write a test class and see if we can retrieve the super class state from serialized data or not.

InheritanceSerializationTest.java



package com.journaldev.serialization.inheritance;



import java.io.IOException;



import com.journaldev.serialization.SerializationUtil;



public class InheritanceSerializationTest {



    public static void main(String[] args) {

        String fileName = "subclass.ser";

         

        SubClass subClass = new SubClass();

        subClass.setId(10);

        subClass.setValue("Data");

        subClass.setName("Kartik");

         

        try {

            SerializationUtil.serialize(subClass, fileName);

        } catch (IOException e) {

            e.printStackTrace();

            return;

        }

         

        try {

            SubClass subNew = (SubClass) SerializationUtil.deserialize(fileName);

            System.out.println("SubClass read = "+subNew);

        } catch (ClassNotFoundException | IOException e) {

            e.printStackTrace();

        }

    }



}

When we run above class, we get following output.

1

SubClass read = SubClass{id=10,value=Data,name=Kartik}

So in this way, we can serialize super class state even though it’s not implementing Serializable interface. This strategy comes handy when the super class is a third-party class that we can’t change.

Serialization Proxy Pattern
Java Serialization comes with some serious pitfalls such as;

·                  The class structure can’t be changed a lot without breaking the serialization process. So even though we don’t need some variables later on, we need to keep them just for backward compatibility.

·                  Serialization causes huge security risks, an attacker can change the stream sequence and cause harm to the system. For example, user role is serialized and an attacker change the stream value to make it admin and run malicious code.

Serialization Proxy pattern is a way to achieve greater security with Serialization. In this pattern, an inner private static class is used as a proxy class for serialization purpose. This class is designed in the way to maintain the state of the main class. This pattern is implemented by properly implementing readResolve()and writeReplace() methods.

Let us first write a class which implements serialization proxy pattern and then we will analyze it for better understanding.

Data.java



package com.journaldev.serialization.proxy;



import java.io.InvalidObjectException;

import java.io.ObjectInputStream;

import java.io.Serializable;



public class Data implements Serializable{



    private static final long serialVersionUID = 2087368867376448459L;



    private String data;

     

    public Data(String d){

        this.data=d;

    }



    public String getData() {

        return data;

    }



    public void setData(String data) {

        this.data = data;

    }

     

    @Override

    public String toString(){

        return "Data{data="+data+"}";

    }

     

    //serialization proxy class

    private static class DataProxy implements Serializable{

     

        private static final long serialVersionUID = 8333905273185436744L;

         

        private String dataProxy;

        private static final String PREFIX = "ABC";

        private static final String SUFFIX = "DEFG";

         

        public DataProxy(Data d){

            //obscuring data for security

            this.dataProxy = PREFIX + d.data + SUFFIX;

        }

         

        private Object readResolve() throws InvalidObjectException {

            if(dataProxy.startsWith(PREFIX) && dataProxy.endsWith(SUFFIX)){

            return new Data(dataProxy.substring(3, dataProxy.length() -4));

            }else throw new InvalidObjectException("data corrupted");

        }

         

    }

     

    //replacing serialized object to DataProxy object

    private Object writeReplace(){

        return new DataProxy(this);

    }

     

    private void readObject(ObjectInputStream ois) throws InvalidObjectException{

        throw new InvalidObjectException("Proxy is not used, something fishy");

    }

}

·                  Both Data and DataProxy class should implement Serializable interface.

·                  DataProxy should be able to maintain the state of Data object.

·                  DataProxy is inner private static class, so that other classes can’t access it.

·                  DataProxy should have a single constructor that takes Data as argument.

·                  Data class should provide writeReplace() method returning DataProxy instance. So when Data object is serialized, the returned stream is of DataProxy class. However DataProxy class is not visible outside, so it can’t be used directly.

·                  DataProxy class should implement readResolve() method returning Data object. So when Data class is deserialized, internally DataProxy is deserialized and when it’s readResolve() method is called, we get Data object.

·                  Finally implement readObject() method in Data class and throw InvalidObjectException to avoid hackers attack trying to fabricate Data object stream and parse it.

Let’s write a small test to check whether implementation works or not.

SerializationProxyTest.java



package com.journaldev.serialization.proxy;



import java.io.IOException;



import com.journaldev.serialization.SerializationUtil;



public class SerializationProxyTest {



    public static void main(String[] args) {

        String fileName = "data.ser";

         

        Data data = new Data("Pankaj");

         

        try {

            SerializationUtil.serialize(data, fileName);

        } catch (IOException e) {

            e.printStackTrace();

        }

         

        try {

            Data newData = (Data) SerializationUtil.deserialize(fileName);

            System.out.println(newData);

        } catch (ClassNotFoundException | IOException e) {

            e.printStackTrace();

        }

    }



}

When we run above class, we get below output in console.

1

Data{data=Kartik}

If you will open the data.ser file, you



How to create a non serialization Class to Serialization Class
Step 1>Create A non serialization Class like below





/**

*

* @author Kartik Mandal

* Blog kartikchandramandal.blogspot.com

* A non serialization class convert to Serialization class by this algorithm

* @date Feb 25, 2015

*/

package com.kartik;


public class SuperClass {

    private int id;

     private String value;

    transient private String dance;

      

     public int getId() {

         return id;

     }

     public void setId(int id) {

         this.id = id;

     }

     public String getValue() {

         return value;

     }

     public void setValue(String value) {

         this.value = value;

     }

  /**

   * @return the dance

   */

  public String getDance() {

   return dance;

  }

  /**

   * @param dance the dance to set

   */

  public void setDance(String dance) {

   this.dance = dance;

  }

}



 
 

Step 2> Create A Serialization Class that extend to Non Serialization Class like Below  
N:B  here must be mention four rules should be there
  A> Need to implements Serializable, ObjectInputValidation;
  B> private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException  method
  C> private void writeObject(ObjectOutputStream oos) throws IOException mthod 
  D> public void validateObject() throws InvalidObjectException  method 



package com.kartik;


import java.io.IOException;

import java.io.InvalidObjectException;

import java.io.ObjectInputStream;

import java.io.ObjectInputValidation;

import java.io.ObjectOutputStream;

import java.io.Serializable;



final public class SubClass extends SuperClass implements Serializable, ObjectInputValidation{



    private static final long serialVersionUID = -1322322139926390329L;



    private String name;



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }

     

    @Override

    public String toString(){

        return "SubClass{id="+getId()+",value="+getValue()+",name="+getName()+"}";

    }

     

    //adding helper method for serialization to save/initialize super class state

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException{

        ois.defaultReadObject();

         

        //notice the order of read and write should be same

        setId(ois.readInt());

        setValue((String) ois.readObject());

         

    }

     

    private void writeObject(ObjectOutputStream oos) throws IOException{

        oos.defaultWriteObject();

         

        oos.writeInt(getId());

        oos.writeObject(getValue());

    }



    @Override

    public void validateObject() throws InvalidObjectException {

        //validate the object here

        if(name == null || "".equals(name)) throw new InvalidObjectException("name can't be null or empty");

        if(getId() <=0) throw new InvalidObjectException("ID can't be negative or zero");

    }

     

}



Step 3> Create A serialization utility class  where convert to serialization and deserialization method


package com.kartik;





import java.io.FileInputStream;



import java.io.FileOutputStream;



import java.io.IOException;



import java.io.ObjectInputStream;



import java.io.ObjectOutputStream;





/**

* A simple class with generic serialize and deserialize method implementations

*

* @author Kartik

*

*/

public class SerializationUtil {





// deserialize to Object from given file



public static Object deserialize(String fileName) throws IOException,




ClassNotFoundException {

FileInputStream fis = new FileInputStream(fileName);



ObjectInputStream ois = new ObjectInputStream(fis);



Object obj = ois.readObject();



ois.close();



return obj;




}




// serialize the given object and save it to file



public static void serialize(Object obj, String fileName)



throws IOException {



FileOutputStream fos = new FileOutputStream(fileName);



ObjectOutputStream oos = new ObjectOutputStream(fos);



oos.writeObject(obj);





fos.close();




}





}
 

Step 4> Test That Non Serialization Object now it convert to Serialization


package com.ser;


import java.io.IOException;


public class InheritanceSerializationTest {


  public static void main(String[] args) {

        String fileName = "subclass.ser";

         

        SubClass subClass = new SubClass();

        subClass.setId(10);

        subClass.setValue("Kartik");

        subClass.setName("Mandal");

         

        try {

            SerializationUtil.serialize(subClass, fileName);

        } catch (IOException e) {

            e.printStackTrace();

            return;

        }    

        try {

            SubClass subNew = (SubClass) SerializationUtil.deserialize(fileName);

            System.out.println("SubClass read = "+subNew);

        } catch (ClassNotFoundException | IOException e) {

            e.printStackTrace();

        }

    }



}

Out put:

SubClass read = SubClass{id=10,value=Kartik,name=Mandal}









What is serialization?

To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable.



What is the use of Serialization?

As written above serialization will translate the Object state to Byte Streams. This Byte stream can be used for different purpose.



Write to Disk

Store in Memory

Sent byte stream to other platform over network

Save byte stream in DB(As BLOB)





Difference b/w Serializable and Externalizable Interfaces?



So lets discuss what are the differences in both the interfaces and how to decide which one should be used -



Serializable Interface is based on a  recursive algorithm i.e during the serialization besides the fields it will serialize all the objects that can be reached through its instance variables i.e. all the objects that can be reached from that object (provided that all the classes must implement Serializable Interface). This includes the super class of the object until it reaches the “Object” class and the same way the super class of the instance variables until it reaches the “Object” class of those variables. Basically all the objects that it can read. And this leads to a lot of overhead when we want to save only few variable or a small data as compared to the class

For eg - If you have a class named Mercedes and you just want to store the car series and its car identification number then you can not stop at this only and will have to store all the fields of that class and also of its super class(if exists and implements serializable interface) and a lot more.

Serializable is a marker interface and hence no need to override any method and whenever there is any change in the entity or bean classes you just need to recompile your program whether in the case of Externalizable interface you have to implement writeExternal() and readExternal() methods which contains the logic to store and retrieve data and with changes you might need to do changes in the code logic.

Serializable provides you both options i.e. you can handle the process by your own or you can leave it for the process to be done in the default way but in Externalizable you have to provide the logic of the process and have full control over the serialize and deserialize process.

Serializable involves reflection mechanism to recover the object. This also adds the the metadata i.e. class description, variable information etc of all the serializable classes in the process which adds a lot of data and metadata into the stream and consumes bandwidth and a performance issue.

A public no-arg constructor is needed while using Externalizable interface but in Serializable it reads the required information from the ObjectInputStream and this is why it uses reflection mechanism.

You need to define serialVersionUID in case of Serializable and if it is not explicitly defined it will be generated automatically and it is based on all the fields, methods etc of the class and it changes every time you do the changes in the class. You if current id does not match with generated id you will not be able to recover the previously stored data. Since the ID is generated every time it will take considerable amount of time which is not a case with externalizable interface.

Externalizable interface is fast and also consumes less memory as compared to the other one. Follow this link to see test results.







What is Marker interfaces in Java and why required?



Marker interface in Java is interfaces with no field or methods or in simple word empty interface in java is called marker interface. Example of market interface is Serializable, Clonnable and Remote interface. Now if marker interface doesn't have any field or method or behavior they



Your question should really be how does the compiler handle marker interfaces, and the answer is: No differently from any other interface. For example, suppose I declare a new marker interface Foo:



public interface Foo {

}

... and then declare a class Bar that implements Foo:



public class Bar implements Foo {

  private final int i;



  public Bar(int i) { this.i = i; }

}

I am now able to refer to an instance of Bar through a reference of type Foo:



Foo foo = new Bar(5);

... and also check (at runtime) whether an object implements Foo:



if (o instanceof Foo) {

  System.err.println("It's a Foo!");

}

This latter case is typically the driver behind using marker interfaces; the former case offers little benefit as there are no methods that can be called on Foo (without first attempting a downcast).

     

There has to be a way JVM understands that this interface is a marker interface and if JVM encounters a marker interface it should take some action. If i declare an interface with no methods and hope that any class implementing it can be serialized , it'll not work 

The JVM doesn't care. It is the Java code that does the checking. 

     

The answer given is pretty perfect and clear. I was going through "ObjectOutputStream" class and writeObject0 method is checking whether Object is of Serializable instance type(obj instanceof Serializable) or not. If not it is throwing NotSerializableException. Apart from that most of the regular classes like String, ArrayList etc already implementing Serializable interface, so sometimes it skips out from our head to check whether Class we want to serialize is implementing the interface





Defining an user-defined marker interface in Java



Let's define a user-defined marker interface. Let's say there is an app suporting a medical store inventory and suppose you need a reporting showing the sale, revenue, profit, etc. of three types of medicines - allopathic, homeopathic, and ayurvedic separately. Now all you need is to define three marker interfaces and make your products (medicines) implement the corresponding ones.





public interface Allopathic{}

public interface Homeopathic{}

public interface Ayurvedic{}





In your reporting modules, you can probably get the segregation using something similar to below:-





for (Medicine medicine : allMedicines) {

if (medicine instanceof Allopathic) {

//... update stats accordingly

}

else if (medicine instanceof Homeopathic) {

//... update stats accordingly

}

else if (medicine instanceof Ayurvedic) {

//... update stats accordingly

}

else {

//... handle stats for general items

}

}





    


Difference between Serilization and Externalization
Serialization
Externalization
  • It is meant for Default Serialization
  • Here everything take care by JVM and programmer doesn’t have any control
  • In serialization total object will be saved to the file always whether it is required or not.
  • Relatively performance is low
  • Serialization is best choice if we want to save total object to the file
  • It doesn’t contain any method. It is Marker Interface
  • It’s implemented class not required to contain public no-argument constructor.
  • Transient key is a vital things in serialization
  • It is meant for Customized serialization
  • Here everything takes care by programmer and JVM doesn’t have any control.
  • In Externilization based on our required. We can save either total object or partial object.
  • Relatively performance is high
  • It is the best choice when if want to save part of the object to a file
  • It contains two method writeExternal() and readExternal(). So it is not a marker interface
  • It’s implanting time it is mandatory to create a no-argument constructor. Otherwise we will get run time exception saying InvalidClassException
  • This place transient key word is not play any role





Other Links:
Inheritance Understand Part 1
Inheritance Understand Part 2
Inheritance Understand Part 3
Robot move
GENERATING KEYSTORE FILES
Previous
Next Post »