What is Marker Interface in Java example and usage

What is Marker Interface in Java example and usage

What is marker interface in java

In this Java refresher article we’ll get to know Marker interface in Java – example and the applicable use cases. Then we will learn how to create marker interface in java with an example. In the last we will see a few inbuilt JDK interfaces used as marker, the use cases and alternatives of marker interface.

Marker Interface

An empty interface that has no methods or constants inside it, is known as a marker interface.

It shows the run-time type meta information about objects so the JVM has additional details about this object. By implementing such interfaces a class shows specific behavior/features. For example – Cloneable and Serializable are JDK in-built marker interfaces.

The marker interface appear as any other interface (but empty) from outside –

public interface cloneable {
}

Note

  • These are also known as tagging interface.
  • You can rather use annotations in place of Marker interfaces to provide the same metadata marker interfaces provide.

In this JAVA refresher article, we’ll try to cover below. As interface and more specifically, marker interface do appear frequently in technical interviews, you need to pay attention so that you don’t blow the core java interview you were preparing for 🙂

  1. How does JVM invoke the specific behavior of Marker Interfaces?
  2. How can you write our own marker interface? Provide a simple user defined marker interface for easy understanding?
  3. Can you differentiate – a marker interface vs annotation?

Now, as I mentioned above that such interfaces do not have any field or methods defined in them, the question arises then why do we need marker interface at all? This is a very common core java interview question and anyone having basic programming skills in the java language is expected to know the answer. We will explore below in detail about the use of marker interface in Java and its need.

What is a Marker Interface in Java – built in with JDK

Java has some built in marker interfaces which are shipped with the JDK. These interfaces are used for some predefined operations, for example cloneable interface which is used to mark an object for cloning. Main built in marker interfaces are –

Following table gives the list of all the Marker interfaces.

Maker interfaceFunctionality
1. java.io.SerializableIndicate the JVM that the object can be serialized.
2. java.lang.CloneableIndicate the JVM that the object can be cloned.
3. javax.servlet.SingleThreadModelonly one object of the servlet for one request is created
4. javax.ejb.EnterpriseBeanthe object can participate in transactions
5. java.util.RandomAccessthe elements of the data structure can be randomly retrieved fast (introduced in jdk1.5)
6. java.rmi.Remotethe object can invoke the methods on a remote machine
7. java.util.EventListenerAll event listeners extend this interface

How does tagging work?

Lets consider Cloneable. If we want to clone an object that does not implement cloneable, then JVM will throw CloneNotSupportedException. However, if the object is tagged with Cloneable then JVM knows that it has to call Object.clone() for this object. Thus, marker interface ‘Cloneable’ is the indication to JVM for performing cloning.

Marker interface in Java example

Cloneable

As we discussed before, Cleanable is a built in marker interface in Java is also a belonging to java.lang package. It creates a duplicate/or a copy of the original object. The object to be cloned is tagged with Cloneable interface by implementing it. If there’s an attempt to clone an object without implementing Cloneable, by invoking clone(), it throws the ClassNotSupportedException. The reason for this is that the Cloneable is an marker/or indicator to the JVM that we can call the Object.clone() method on this object.

To do actual cloning work – this class (the one implementing Cloneable) must override the clone() coming from parent Object class.

Let’s understand this with a marker interface in java example –

package com.ex.marker;

public class Employee implements Cloneable {

	private String name;
	private int age;
	private String department;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public void printDetails() {
		System.out.println("Employee Name: " + name + " , Age: " + age + " , Department: " + department);
	}

	public static void main(String[] args) {
		System.out.println("Testing cloning");
		Employee e = new Employee();
		e.setName("John");
		e.setAge(25);
		e.setDepartment("Admin");
		e.printDetails();

		try {
			Employee cloned = (Employee) e.clone();
			cloned.printDetails();
		} catch (CloneNotSupportedException e1) {
			e1.printStackTrace();
		}
		System.out.println("Finished cloning test");
	}
}

Output is generated as –

Testing cloning
Employee Name: John , Age: 25 , Department: Admin
Employee Name: John , Age: 25 , Department: Admin
Finished cloning test

Serializable

This built in marker interface is used in serializing and deserialing an object. Its defined in java.io package. Just like Cloneable, a class implementing Serializable tells the Jvm that this class may be serialized by calling ObjectOutputStream.writeObject(). If there’s an attempt to serialize a class without implementing this interface, then a NotSerializableException is thrown.

Side note on Serialization

Serialization is used to convert an object’s state from memory to a file or DB by converting the object into byte stream.
Deserialization is the process to convert byte stream into the object by reading the object’s state from a file or DB it was converted into earlier.

Marker Interface - Serializable
Marker Interface – Serializable

Serialization (writing) can be achieved with the ObjectOutputStream class and deserialization (reading) can be achieved with the ObjectInputStream class.

Lets implement this with one Serialization example –

package com.ex.marker.serialize;

import java.io.Serializable;

public class Employee implements Serializable {

	private static final long serialVersionUID = -3403678312190693537L;
	private String name;
	private int age;
	private String department;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}
	
}


// --------------------------------


package com.ex.marker.serialize;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializationTest {

	public static void main(String[] args) {
		System.out.println("Going to serialize an object.");
		Employee e = new Employee();
		e.setName("John");
		e.setAge(25);
		e.setDepartment("Admin");
		
		try {
			FileOutputStream fout=new FileOutputStream("emp_john.out");
			ObjectOutputStream out = new ObjectOutputStream(fout);
			out.writeObject(e);    
			out.flush();    
			out.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		}    

		System.out.println("Done!!");
	}
}


Going to serialize an object.
Done!!

Deserialization of the same object –

package com.ex.marker.serialize;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class DeserializationTest {

	public static void main(String[] args) {
		System.out.println("Going to deserialize an object.");
		try {
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("emp_john.out"));
			Employee e = (Employee) in.readObject();
			System.out.println("completed deserialization of : " + e.getName() + " in " + e.getDepartment() + " Department!!");
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
Going to deserialize an object.
completed deserialization of : John in Admin Department!!

Remote

This interface is part of java.rmi package. We must mark the object with remote interface if we want it to be accessible remotely. Such objects tagged with Remote are then accessed from another machine (host) or JVMs.

How to create custom marker interface in Java example program

Apart from jdk/ built-in marker interface, Java lets us define our own/custom marker interface. Let’s create one –
For example, we could create an audit marker that signals whether if a change in object’s instance in the database requires to be audited:

public interface Auditable {
}

In order to audit an entity’s state in the database, the object should be marked with the Auditable interface:

public class Employee implements Auditable {
     :::::::::::::::::::::::
}

Suppose we have a DAO and its method to audit object’s state change in db. We need to define audit() method in such a way that state change for the objects tagged with our marker interface only get captured.

public class EmployeeDao {

public boolean audit(Object object) {
    if (object instanceof Auditable) {
        insertAudit(); // inserts the change into audit table
    }
    return true;
}
}

Here we are giving a signal to the JVM about runtime behavior of our Employee objects. Since employee implements our Auditable marker interface, its entry needs to be created in the audit table when the object’s state changes in the DB. For other objects’ which are not Auditable (i.e. not tagged with Auditable), there change in state is not captured.

Alternatives to Marker Interface in Java

There are 2 more ways, which in effect can give similar results to Marker Interfaces.

Internal Flags: It can be used in place of marker interface to indicate any specific operation.

Is it so simple to achieve the same functionality with an internal flag? Why do we have Marker Interface created at all then? This make sense, right? Yes this can be done by using a boolean flag or a String but doesn’t marking a class like Serializable or Clonneable makes it more readable and it also allows to take advantage of Polymorphism in Java.

Annotations: Since Java 5, you could use annotations for the similar results as Marker Interface. By adding annotations to any class, we can perform specific metadata information/signal for JVM.

Marker Interfaces vs. Annotations

Java has given us an alternative to get the same results as the marker interfaces with the help of annotations. We can use annotations as signal to JVM for specific actions to any java class – just like we can do for Marker Interface.

So, what’s difference with the annotations?

With interfaces, we can be benefitted from the polymorphism – a core concept in Java, this is not the case with annotations. As a result, we can also add more restrictions to the marker interface.

Lets understand this with an example. Let’s add a restriction that we need to capture audit information for only a PermanentEmployee type.


public interface Employee{
	double getName();
	double getDepartment();
}

In this case, our marker interface, let’s call it AuditableEmployee, will look like the following:

public interface AuditableEmployee extends Employee {
}

Then our class will implement the marker interface:

public class PermanentEmployee implements AuditableEmployee {
// implementation details
}

// --------------------
public class TempEmployee implements Employee {
// implementation details
}

Therefore, all AuditableEmployee implementations are also Employee implementations. Obviously, we can’t do that using annotations.

Only tradeoff here is arguement against polymorphism i.e. that every class extending PermanentEmployee will automatically implement AuditableEmployee interface. This is a design decision and depends on the use case.

Marker Interfaces vs. Common Interfaces

Lets consider the previous example one more time. We will still be getting the same results if we modify our DAO’s delete() method to test if the object is a Shape, instead of validating if it’s an Auditable:

public class ShapeDao {
// other dao methods 

public boolean delete(Object object) {
    if (!(object instanceof Shape)) {
        return false;
    }

    // delete implementation details

    return true;
}

}
So what’s the purpose of a marker interface when the same things can be done by a normal interface?

Let’s imagine that, in addition to the Employee type, we also want to remove the Person type from the db. In that case, we have two options to do that:

Option 1 – Add an additional check to validate if the object to delete is an instance of Person or not.

public boolean delete(Object object) {
	if (!(object instanceof Shape || object instanceof Person)) {
		return false;
	}
	return true;
}


But what if there are more such types (Department for example) which get updated in the database as well? Should we change our method for every new type? That doesn’t sound like a good option.

Option 2 – Let Person type implement the Shape interface, which acts as a marker interface. But is a Person object really a Shape? The answer is clearly no, and that makes the second option worse than the first one.

So, here’s the trade off, you could still do the same thing with a general interface, but that will lead to a poor design.

Use of Marker Interface in Java

These type of interfaces are helpful to add specific metadata to a class so that a signal can be generated for JVMs. Implementing an empty interface without any method declarations tells the compiler to do some predefined operation on it.

  • Marker Interfaces are used to send signal to compiler or JVM. JVM may perform some special operation on the class if its marked.
  • Built-in marker interface in JDK available to make a class Cloneable or Serializable.
  • It can logically divide the code and categorize it. Own custom marker interface can be created, which is a good way to classify code.
  • You can create marker interface to logically divide your code and if you have your own tool than you can perform some pre-processing operation on those classes. Particularly useful for developing API and framework like Spring or Struts.
  • After the introduction of Annotation on Java5, Annotation is better choice than marker interface and JUnit is a perfect example of using Annotation e.g. @Test for specifying a Test Class. The same can also be achieved by using Test marker interface.

Annotating as comments

You can use the marker interface in Java for commenting as well. For example – if you mark a class at @ThreadSafe – it will better communicate to fellow developers that the class is designed to be a thread-safe class and could be used that way, also new changes shouldn’t violate that guarantee. Again, annotating the class with @ThreadSafe is a much better choice as it looks far better than implementing ThraedSafe marker interface.

Summary

To summarize this quick java refresher article – marker interface something/a signal to the compiler, JVM or any other tool. For example when you mark your class as Serializable it just tells that this class can be converted to bytes. Annotation may be a better way of doing the same thing though. We also covered marker interface in Java example, use cases and alternative ways to implement them.

  • In this article, we discussed some of the questions which get discussed in core java interview –
  • What are marker interfaces in Java? What are their usage?
  • Built-in examples of this type of interfaces.
  • Creating a custom marker interface and differentiate with an annotation.
  • Then, we summarized by analyzing why using marker interface in some cases be preferable to a traditional interface.

As always, you can find the above code on GitHub.

Further Reading

Want to learn more about JAVA interfaces and core concepts in OOPs? Refer to below articles and start preparing for your core java interview right away –

Feel free to ask any questions in the comment section below and we will try to revert as soon as possible.

Leave a Reply

Your email address will not be published. Required fields are marked *