Marker Interface in Java
An interface that does not have any methods, fields, or constants, i.e., an empty interface in java, is known as a Marker or Tag Interface.
It is used to deliver type information at runtime to the JVM so that it can take some action based on the information received.
One of the main purposes behind the ideology of marker interfaces is to convey to the JVM that the class implementing this type of interface has some extra functionalities.
Popular examples of marker interfaces in Java include Cloneable, Serializable, Remote Interface.
What is Marker Interface?
Marker interfaces are interfaces that don't have fields, methods, or constants. In other words, a marker or tag interface is an empty interface. It provides information about an object's run-time type.
Because of this, the JVM and compiler have additional information about an object. Examples of marker interfaces include the Serializable and Cloneable interfaces. To put it briefly, a marker interface denotes a signal or command to the JVM.
The interface for a marker must be empty, but the declaration is the same as for an interface in Java. Following is the syntax of Marker Interface in Java :
Syntax of Marker Interface in Java
Alternatives of Marker Interface
- Interface in Java is an abstract type that is used to define a behavior that class(s) must implement.
Note: An abstract data type is a data type where only behaviour is defined but not implemented. Defining a behaviour without any implementation means declaring a function by defining it.
- Marker Interface in Java is nothing but a special type of interface made empty on purpose.
As marker interfaces in Java can be indicated as a signal or command to the JVM, can't there be any other way to signal the JVM? Yes, there are alternatives of Marker Interfaces in Java.
Main alternatives of Marker Interfaces include:
- Internal Flags: Internal flags in a class can be used to indicate to the JVM that some extra special operations need to be allowed to the respective class.
Example:
Explanation:
Here, the variable allowSpecialBehavior is set to true. The JVM can use this to assign special behaviour to the objects of this class.
- Annotations: Annotations in Java act as tags that represent the metadata attached to class(s), interface(s), or method(s) to indicate additional information that can be used by JVM to grant special operations to the respective class.
Example:
Explanation: Here, the @Service annotation used above the class A definition tells JVM that class A is a Service class. A Service class is used by a client to interact with the functionalities in your application.
Uses of Marker Interface
The main use of the Marker Interface in Java is to convey to the JVM that the class implementing an interface of this category must be granted some special behavior.
For example, when a class implements the Serializable interface, a marker interface, the JVM is informed that the class's objects can be serialized. Similarly, when a class implements the Cloneable Interface, the JVM is informed that the class's objects can be cloned.
Note: Cloning is creating an exact copy of an object. Serialization is converting an object into a static stream (sequence) of bytes, which can be saved to a database or transferred over a network.
Examples of Marker Interface in Java
JDK Marker Interface in Java Examples are:
java.io.Serializable, java.lang.Cloneable, java.rmi.Remote, javax.servlet.SingleThreadModel, javax.ejb.EnterpriseBean, java.util.RandomAccess, java.util.EventListener, etc. We will look at 3 of the most popular marker interface in Java:
a.) Cloneable Interface: Cloneable Interface in Java is a marker interface. It belongs to java.lang package. It is used to create a clone or copy of an object with some other name. If we want to clone the objects of a class, then that class has to implement the Cloneable interface. This is used to indicate the JVM that the clone() method of the Object class can be used by the objects of the class that have implemented the Cloneable Interface.
Syntax:
Point to Note: If a class has not implemented the Cloneable Interface, and its objects call the clone() method, it throws an exception named CloneNotSupportedException.
Example 1: In the below example, we will notice that a class that has not implemented the Cloneable interface and its objects invoke the clone() method causes the JVM to throw an exception at runtime.
Output:
Explanation:
Here, we have a Plant class and created an object p1 of the Plant class. We are trying to clone the object p1 with another name, p2. However, since the Plant class has not implemented the Cloneable Marker Interface, the execution stops at runtime with CloneNotSupportedException.
Example 2:
The example below is the same as the previous example. This time, the Plant class has implemented the Cloneable Interface. Thus, the objects of the Plant class can invoke the clone() function without any problem.
Output:
Explanation: Here, we have a Plant class, and we have created an object p1 of the Plant class. We are trying to clone the object p1 with another name, p2.
Since the plant class has implemented the Cleanable Marker Interface in Java, a clone of p1 is made and stored in p2.
b.) Serializable Interface: Serializable Interface is a Marker Interface in Java, i.e, it is an empty interface as it has no methods, fields or constants, etc. Its definition is present in Java's IO package.
Syntax:
Note: Serialization is the process of conversion of the state of an object into a byte stream so that it can be saved on the disk or in a database or shared over a network. On the other hand, deserialization does the opposite, i.e, conversion of a byte stream into an object.
If we want to save the state of a class object into physical memory (e.g., a file) or retrieve an object's state that is already stored in the physical memory (e.g., a file), we must make it Serializable. To make a class Serializable, it needs to implement the Serializable Interface.
Example: In the example below, we demonstrate that a class that implements the Serializable marker interface makes its objects eligible to be serialized and deserialized.
Output:
Explanation:
Here, we have created a Student class implementing the Serializable Interface. This allows the objects of the Student class to be serialized and deserialized. In the main function, we have created an object s1 of the class Student and stored it on the disk in a file named S1_Info.txt.
Just after that, we retrieved the same s1 object from the file S1_Info.txt and stored it in s2.
c.) Remote Interface:
Remote Interface is a marker interface in Java, defined in java.rmi package. It is used for Remote Method Invocation purposes.
Note: Remote Method Invocation or RMI is a mechanism that allows an object residing in one system JVM to access/invoke an object running on another system JVM.
Syntax:
Example: The example below shows the use of Remote Interface to demonstrate the phenomenon of remote method invocation. Here, an object is created and bound (using the rebind() function) with a URL on the localhost server. This stub is accessed from another Java file by using the lookup() function. Then, using this stub, the function checkEvenOdd() is invoked with the parameter as an integer variable.
Output(s): Terminal 1 (For Server)
Output(s): Terminal 2 (For Client)
Explanation:
Here, we have created an EvenOddCheckerInterface which extends the Remote Interface, thereby making the subclasses of EvenOddCheckerInterface as RMI enabled. A remote class named EvenOddCheckerRemote is created which implements the EvenOddCheckerInterface, which provides the definition for checkEvenOdd() method.
There is a server class and a client class created. The server class creates an object of EvenOddCheckerRemote and binds it to a URL. The client creates a stub and accesses the EvenOddCheckerRemote object using the EvenOddCheckerInterface instance.
And when it access the object in the stub, it calls the checkEvenOdd() method with an integer parameter, for which it gets a boolean value referring to an even or odd number, and accordingly, it prints its result.
2.) Custom Marker Interface in Java: We can create our own Marker Interface in Java, as shown in the below example.
Example: In the below example, we have created our own custom marker interface. We have made 2 classes Employee and Customer. We are classifying the objects of these 2 classes in 2 different lists, using the marker interface.
Output(s):
Explanation:
Here we have created a marker interface with the name EmployeeMarkerInterface. Employee class implements the marker interface, whereas the Customer class does not. In the main function, we have created 2 employees and 2 customers.
We are segregating employees and customers using the marker interface.
Marker Interfaces vs Annotations
Annotations in Java can be applied to any class so that the JVM can assign special behavior to the respective class. This makes us realize that both Marker Interfaces and Annotations are the same things. But the point here to note is that they are not completely similar.
One of the major differences is due to Polymorphism. Marker Interfaces follow the concepts of polymorphism.
Let's make an Interface as Marker Interface, and some class has implemented this marker interface. All the child classes that extend this class will automatically and indirectly have implemented the marker interface. This behavior is not included in Annotations.
This fact can sometimes be used as an advantage by the programmer, and sometimes it can also be a disadvantage.
Example:
There is a class named as KnowledgeContent, which is made Serializable (Marker Interface) as shown below in the code.
There are 2 child classes of KnowledgeContent class, i.e, Text and Video. We only want the Text class to become Serializable, not the Video class.
However, since marker interfaces follow polymorphism, all children of a serializable class are also serializable. So Text and Video classes both are Serializable now, as shown below:
But if we want to make only the Text class as Serializable and not the Video class, so we will have to use @Serializable Annotation, as shown below:
The above example shows when polymorphism in Marker Interfaces can act as a disadvantage. But what if we had a requirement in which we wanted all the child classes to also become Serializable if the parent class is Serializable?
In that case, polymorphism in Marker Interfaces can act as an advantage.
Why? If we use annotations, we will have to manually add @Serializable above the definition of each child class, which will be a very boring repetitive task.
Marker Interfaces vs Typical Interfaces
Normal interfaces can also be used as a marker interface, but there will be issues with that. Let's find out by understanding the below example.
Example: Let's see one example where we are allowing only those objects to be a deletable whose class or some parent class has implemented the Deletable Marker Interface.
Here, we have allowed the deletion of only those objects that directly or indirectly implement the Marker Interface 'DeletableEmployee'. But can we not do the same using a normal Interface. Let's find out below:
Here, we have allowed the deletion of the objects of the classes that have implemented the typical non-marker interface Employee. But if another type of instance comes in the future, say, Consultant, shown as below:
And suppose we want to allow the objects of classes that have implemented the consultant interface to be deleted without using the marker interface. In that case, we will have to modify the logic of the delete() function of the EmployeeDao class as follows:
But what if, in the future, we want to accommodate other instances, like Freelancer, ContractEmployees, etc., to be allowed deletion? Then, each time, we will have to modify the logic of our delete() method of the EmployeeDao class. Thus, opting for the Marker Interface way is a wise choice.
Conclusion
- Marker Interfaces in Java (also known as Tag Interfaces) are empty interfaces, i.e., they do not have any variables or methods declared.
- Marker Interfaces in Java indicate to the JVM that the class(s) that have implemented them should be allowed to perform some special functions.
- Few of the most popular marker interfaces are Cloneable, Serializable, and Remote Interfaces.
- The Cloneable Interface indicates to the JVM that the objects of the class implementing the Cloneable Interface can be cloned by invoking the clone() function.
- The Serializable Interface, on the other hand, indicates to the JVM that the objects of the class implementing the Serializable interface can be serialized, i.e., their state can be stored in memory or shared over a network.
- Remote Interface is used to indicate to the JVM that the objects of the class implementing the Remote Interface can be accessed using the JVM of a Remote System. This enables the Remote Method Invocation phenomenon for the methods of the class implementing the remote interface.