Having written about Java serialization previously, I thought I’d put in some research into the concept of ‘Marker Interfaces’ or ‘Tag Interfaces’. Well, getting matters straight, technically, the word ‘Marker’ is an invention of bloggers and technical writers. Java specification says nothing about an interface being a ‘Marker Interface’. You won’t find the word ‘Marker’ at all..
A marker interface is an interface with no method declarations. They just tell the compiler that the objects of the classes implementing the interfaces with no defined methods need to be treated differently. These Marker interfaces are used by other code to test for permission to do something.
Some well-known examples are
java.io.Serializable – object implement it can be serialized using ObjectOutputStream.
java.lang.Clonable – objects clone method may be called
They are also known as tag interfaces since they tag all the derived classes into a category based on their purpose
On Interfaces..
Well, what exactly is an interface.
One, I would say an interface is a contract. It is a contract which says the class which implements the interface will implement all the methods specified by the interface.
Two, I say interface is an ‘is a’ relationship. For instance, take a class Sedan which implements the interface Car. We can say that the Seday is a Car. Better example, ArrayList implements List and we say ArrayList is a List.
Let’s take the case of a marker interface Serializable. A class, say Document implements Serializable. Document does not have to implement any methods because the interface Serializable does not specify any methods. This is not right. The Serializable interface does not behave similar to the other interfaces.
Also, it does not make sense to say Document is a Serializable. Instead, Document is Serializable. Again, the interface Serializable does not fit in with the rest. Let me add that, for a marker interface the relationship is, ‘IS’. Class Document is Serializable, or the class Person is Clonable.
Interface Serializable..
This is perhaps the most popular Marker Interface. I won’t talk about serializing an object, you can read more on that. here..
1. FileOutputStream fos = new FileOutputStream("temp.out"); 2. ObjectOutputStream oos = new ObjectOutputStream(fos); 3.
Match
m1 = new
Match
(); 4. oos.writeObject(m1);
In the snippet of code above, I am trying to serialize an object m1 of Type Match. The ObjectOutputStream then attempts to serialize the object. If you inspect the ObjectOutputStream source, you can see a check for Serializable happening.
private void writeObject0(Object obj, boolean unshared) trows IOException
.
.
else if (obj instanceof Enum) {
writeEnum((Enum) obj, desc, unshared);
}
else if (obj instanceof Serializable) {
writeOrdinaryObject(obj, desc, unshared);
}
else {
if (extendedDebugInfo) {
throw new NotSerializableException(
cl.getName() + "\n" + debugInfoStack.toString());
} else {
throw new NotSerializableException(cl.getName());
}.
.
They are doing a check to see if the Object to be serialized is of the type Serializable. If it’s not, a suitable exception is thrown.
So, what do we benfit from implementing the Serializable interface here?
‘Marker Interface Pattern’
A marker interface provides a metadata to the class. The metadata being ‘this class is serializable’. Or in cases like the Clonable interface, the marker interface states the class is ‘Clonable’. There is a wiki page on ‘Marker Interface Pattern’.
“The marker interface pattern is a design pattern in computer science, used with languages that provide run-time type information about objects. It provides a means to associate metadata with a class where the language does not have explicit support for such metadata.”
So, the concept of Marker Interfaces came about in Java at a time when there was no support for metadata. But now we have support in terms of Annotations. I can debate that, whatever is achieved through Marker interfaces, can be achieved through Annotations too.
A worthy substitute?
So, is annotation a worthy substitute for Marker Interfaces? I say yes. See the example below.
01: @interface Drivable{
02: }
03: @Drivable
04: public class Car{
05: public void performAction(Object obj){
06: if (!obj.getClass().isAnnotationPresent(Drivable.class)) {
07: throw new IllegalArgumentException("cannot perform action...");
08: }
09: else {
10: //do stuff as require
11: }
12: }
Pretty straightforward stuff. Using a custom annotation ‘Drivable’, we are checking if a class, in this case Car, is Drivable which perfectly satisfies the ‘IS’ rule.
Having said all this, I must add using annotation comes with a catch. The check for ‘IS’ can occur only at runtime, but for a marker interface, it can throw a compile time error. Plus, annotation work on reflection which is a pretty heavy operation.
As a verdict, I can say that going by core Object Oriented norms, Annotations can beat Marker Interfaces anyday.
I need answer for this, please.
http://javapapers.com/core-java/abstract-and-interface-core-java-2/what-is-a-java-marker-interface/ – this says that Runnable is not a marker interface. My Java teacher says otherwise.
Can you pls explain.
I agree with the article you shared. Runnable is not a marker interface. It’s quite debatable how you define a marker interface, but a widely accepted norm is that a ‘Marker interface does not establish a method defenition’. Runnable provides the ‘run()’ method.
What are the arguments your teacher made?