This tutorial explains what is a Marker Interface in Java. It also covers Serialization Deserialization and Cloning in Java with code examples:
We will discuss the last topic under Interfaces, i.e. Marker Interface in Java.
After we are done with the marker interface we will discuss two examples i.e. serializable and cloneable interface in Java. Let’s begin with the Marker interface.
=> Visit Here To Learn Java From Scratch
Table of Contents:
Marker Interface In Java
A marker interface in Java is an empty interface that has no fields or methods. This marker interface tells the compiler that the objects of the class that implement the marker interface are different and that they should be treated differently.
Each marker interface in Java indicates that it represents something special to JVM or compiler.
In Java, we have three interfaces that are Marker interfaces as shown below:
#1) Serializable interface: Serializable is a marker interface present in the java.io package. We can serialize objects using this interface i.e. save the object state into a file.
#2) Cloneable interface: The cloneable interface is a part of the java.lang package and allows the objects to be cloned.
#3) Remote interface: The remote interface is a part of the java.RMI package and we use this interface to create RMI applications. This interface mainly deals with remote objects.
In this tutorial, we will discuss the serializable and cloneable interface. The remote interface will be discussed when we move to RMI in Java.
Serialization In Java
Before we go into the details of the Serializable interface in Java, let’s understand the process of serialization as well as deserialization in Java.
Serialization can be defined as a process by which we convert the object state into its equivalent byte stream to store the object into the memory in a file or persist the object.
When we want to retrieve the object from its saved state and access its contents, we will have to convert the byte stream back to the actual Java object and this process is called deserialization.
This way there may be many instances wherein we need to serialize/deserialize Java objects in a lifetime of Java application.
The process of serialization/deserialization is shown below:
As shown above, serialization converts the object into a stream. Deserialization converts the byte stream back to a Java object.
The entire mechanism of serialization and deserialization is platform-independent. This means that we can serialize the object on one platform and then deserialize it on a different platform.
When we say that we have serialized the Java object, it means that we have called the ObjectOutputStream method writeObject () to write the object to a file.
public final void writeObect (Object obj) throws IOException
Similarly, in the case of deserialization, we call the ObjectInputStream:: readObject () method to read the data from the file that has stored the object.
public final Object readObject () throws IOException, ClassNotFoundException
Java Serializable Interface
Java provides the interface named ‘serializable’ using which we can implement serialization and deserialization in Java.
Serializable interface is a part of java.io package. It is an example of a marker interface we discussed above and0 that has no methods or members. The serializable interface ‘marks’ the Java classes so that the objects of these classes get the capability of persisting themselves.
So the class whose object we need to persist should implement the Serializable interface. Then the object of this class (implementing Serializable interface) will use writeObject () and readObject () methods respectively for serializing and deserializing the class object.
Note that all the wrapper classes and the String class implement the java.io.Serializable by default.
We should fulfill the following condition for an object to be successfully serialized:
- The class whose objects are serialized must implement java.io.Serializable interface.
- All the member fields of the class must be serializable. If a particular field is not serializable then we should mark it as transient.
Conversely, a class is serializable only if it implements the java.io.Serializable interface otherwise it is not serializable.
How To Serialize And Deserialize An Object In Java
When we serialize an object in Java we use objectOutputStream’s writeObject method to write the object to a file.
For deserializing the object in Java we use the ObjectInputStream’s readObject () method to read the contents of the file and read them into an object.
In this example, we have a Student class that implements the Serializable interface. This means that we can serialize or deserialize the objects of the Student class.
In the main method of the Java program, we create a Student class object. Then we create an ObjectOutputStream that points to a FileOutputStream object that in turn points to a file in which we need to write the Student object. Then we call the writeObject () method that writes the object to the file.
On successfully writing the specified object to the specified file, the program gives an appropriate output message. We then deserialize the object by reversing the above process. First, we create an ObjectOutputStream object in which we read the file whose contents are to be read.
We then use the readObject () method to read the contents and cast it to the Student object. Then we print the contents of the Student object.
Serialization/Deserialization Example
The following Java program shows the serialization/deserialization mechanism in Java as discussed above.
import java.io.*; import java.io.Serializable; //Class Student implements class Student implements Serializable{ int id; String name; public Student(int id, String name) { this.id = id; this.name = name; } } class Main{ public static void main(String args[]){ try{ //Create the object of student class Student s1 =new Student(27,"Eddie"); //Write the object to the stream by creating a output stream FileOutputStream fout=new FileOutputStream("Eddie.txt"); ObjectOutputStream out=new ObjectOutputStream(fout); out.writeObject(s1); out.flush(); //close the stream out.close(); System.out.println("Object successfully written to the file"); //Create a stream to read the object ObjectInputStream in=new ObjectInputStream(new FileInputStream("Eddie.txt")); Student s=(Student)in.readObject(); //print the data of the deserialized object System.out.println("Student object: " + s.id+" "+s.name); //close the stream in.close(); }catch(Exception e){System.out.println(e);} } }
Output:
Note that after deserialization, we get the same object that we have serialized earlier as we open the same file again.
Java Transient Keyword
A transient keyword is used to make a data member transient i.e. we do not want to serialize it.
For example, consider the following class Employee. Here we have the employee Id field along with the other fields. Now if we decide that the Employee Id field should not be serialized then we declare it as ‘transient’.
An example Java program is given below.
import java.io.*; class Employee implements Serializable{ transient int id; String name; public Employee(int id, String name) { this.id = id; this.name = name; } } class Main{ public static void main(String args[]){ try{ //Create the object of Employee class Employee s1 =new Employee(27,"Eddie"); //Write the object to the stream by creating a output stream FileOutputStream fout=new FileOutputStream("Eddie.txt"); ObjectOutputStream out=new ObjectOutputStream(fout); out.writeObject(s1); out.flush(); //close the stream out.close(); System.out.println("Object successfully written to the file"); //Create a stream to read the object ObjectInputStream in=new ObjectInputStream(new FileInputStream("Eddie.txt")); Employee s=(Employee)in.readObject(); //print the data of the deserialized object System.out.println("Employee object: " + s.id+" "+s.name); //close the stream in.close(); }catch(Exception e){System.out.println(e);} } }
Output:
In the above program, we have serialized the Employee object. But note that the Employee id field of the Employee class is declared ‘transient’. Now to check the serialization, we deserialize the object. The output shows the Employee object as ‘0 Eddie’. This means that the Employee Id was not saved to the file.
Java.io.NotSerializableException In Java
The exception of java.io.NotSerializableException is an exception that is thrown when the class is not eligible for serialization. The class that does not implement the Serializable interface becomes ineligible for serialization.
The below Java program demonstrates the NotSerializableException.
import java.io.*; class Employee { transient int id; String name; public Employee(int id, String name) { this.id = id; this.name = name; } } class Main{ public static void main(String args[]){ try{ //Create the object of Employee class Employee s1 =new Employee(27,"Eddie"); //Write the object to the stream by creating a output stream FileOutputStream fout=new FileOutputStream("Eddie.txt"); ObjectOutputStream out=new ObjectOutputStream(fout); out.writeObject(s1); out.flush(); //close the stream out.close(); System.out.println("Object successfully written to the file"); }catch(Exception e){System.out.println(e);} } }
Output:
As seen from the above program, the Employee class does not implement the Serializable interface. Hence, when we try to serialize the Employee class object, the NotSerializableException is thrown.
Cloneable Interface In Java
Cloning of objects means making a copy of the objects. Java supports object cloning using the “Cloneable” interface. The cloneable interface is a marker interface and is a part of the java.lang package.
When a class implements the Cloneable interface, then it implies that we can clone the objects of this class. The Object class of Java contains the ‘clone()’ method. So Cloneable interface implemented by a particular class authorizes the clone () method to make copies of class instances.
If a class does not implement a Cloneable interface and still invokes the clone () method, then the exception CloneNotSupportedException is thrown by the Java compiler.
Classes implementing the Cloneable interface should override the clone () method.
So what is Object Cloning?
Object cloning is a process using which we create an exact copy of the object using the clone () method of the Object class. For the clone () method to be overridden and invoked, the class needs to implement the Cloneable interface.
The general syntax of the clone () method is given below:
protected Object clone() throws CloneNotSupportedException
The clone () method creates an exact copy of the object with less processing time than that taken for creating a new object using the new keyword.
The below Java program demonstrates the use of the clone () method and the Cloneable interface.
class Student implements Cloneable{ int rollno; String name; //class constructor Student(int rollno,String name){ this.rollno=rollno; this.name=name; } //clone method public Object clone()throws CloneNotSupportedException{ return super.clone(); } } class Main{ public static void main(String args[]){ try{ Student s1=new Student(101,"Lissa"); //clone the s1 object Student s2=(Student)s1.clone(); System.out.println("Original Student object: " + s1.rollno+" "+s1.name); System.out.println("Cloned Student object: " + s2.rollno+" "+s2.name); }catch(CloneNotSupportedException c){} } }
Output:
In this program, we have a Student class implementing the Cloneable interface. It also overrides the clone () method by calling the super.clone () method. In the main method we create a new Student object and then call the clone () method on this object that returns the new Student object.
Clone Array In Java
We explored the cloning of arrays in our tutorial on Arrays. Since Java arrays implement Cloneable interface by default, they need not be explicitly implemented. When the one-dimensional array is cloned, a deep copy of the array is generated. When a 2-dimensional array is cloned, then a shallow copy is made.
Making a shallow copy is the default behavior of the clone () method in Java. But most of the time we desire deep cloning. In deep cloning, we make a copy of the object member by member and create a clone that is independent of the original object. Any changes then made to the clone object will not reflect in the original object.
The following Java program shows the cloning of a one-dimensional array.
class Main { public static void main(String args[]) { //define an array int intArray[] = {2,6,3,7,1,8}; //invoke clone () method on intArray int cloneArray[] = intArray.clone(); //print the arrays. System.out.println("Original intArray:"); for (int i = 0; i < intArray.length; i++) { System.out.print(intArray[i]+" "); } System.out.println(); System.out.println("Cloned Array:"); for (int i = 0; i < cloneArray.length; i++) { System.out.print(cloneArray[i]+" "); } System.out.println("\n"); } }
Output:
Clone List In Java
The below program shows how to use a clone () method to clone a list in Java.
import java.util.ArrayList; import java.util.Arrays; import java.util.List; // MyList Class implementing cloneable class MyList implements Cloneable { String name1; String name2; // Constructor MyList(String name1, String name2) { this.name1 = name1; this.name2 = name2; } // To print the objects in the desired format @Override public String toString() { return "Hello " + name1 + "," + name2 + "\n" ; } // Overriding the clone method @Override protected MyList clone() { return new MyList(name1 , name2); } } class Main { public static void main(String[] args) { // Create a list List<MyList> original = Arrays.asList( new MyList("Sydney","Rose"), new MyList("Joe","Ian")); // Create an empty list List<MyList> cloned_list = new ArrayList<MyList>(); // Loop through the list and clone each element for (MyList temp : original) cloned_list.add(temp.clone()); System.out.print(cloned_list); } }
Output:
In the above program, we see that we have created a MyList class that implements the Cloneable interface and inside this class, we override the clone () method that helps us to clone the List. In the main method, we create a list of elements and then clone each element of the list by iterating over the list.
Frequently Asked Questions
Q #1) What is the use of Marker Interface in Java?
Answer: Marker interface that is also known as ‘tagged interface’ tags the class and informs the compiler that this class may implement a special behavior.
Q #2) What are all the Marker Interfaces in Java?
Answer: Serializable, Cloneable, and Remote are the interfaces which are the examples of marker interfaces in Java.
Q #3) Why is serializable a Marker Interface?
Answer: The serializable interface does not have any methods or member variables. It is an empty interface that classifies it as a Marker Interface.
Q #4) Is runnable a Marker Interface?
Answer: No, runnable is not a marker interface. The runnable interface is not empty and it provides a run () method declaration inside it.
Q #5) Why do we need to implement a Cloneable interface?
Answer: By implementing a cloneable interface for a class, we indicate that the objects of this class can be cloned using the clone () method of the Object class. If a class using the clone () method does not implement a cloneable interface then the exception ‘CloneNotSupportedException’ is thrown.
Conclusion
With this tutorial, we have completed our discussion on Interfaces in Java. We have discussed the concept of interfaces, their structure, definition, usage, etc. We have also discussed some of the important interfaces in Java-like Comparable, Comparator, Marker interfaces, etc.
In this tutorial, we discussed two examples of marker interfaces i.e. serializable and cloneable. A serializable interface is used to persist an object. The cloneable interface is used to clone the class objects. Both these interfaces are marker interfaces i.e. they are empty.
But when a class implements them, then they indicate that the compiler can expect some special behavior from the classes implementing them.
For example, when a class implements a Serializable interface then we can serialize or deserialize the class objects and save/retrieve their state.
A class implementing a cloneable interface indicates that we can clone the objects of this class. The default implementation of the clone () method creates a shallow copy of the object while we can override the clone () method to create a deep copy.
=> Explore Complete Java Training Series Here