In earlier versions of Java, Marker Interfaces were the only way to declare metadata about a class
. With the advent of annotation in Java 5
, it is considered that marker interfaces have now no place. They can be completely replaced by Annotations
, which allow for a very flexible metadata capability. Everything that can be done with marker interfaces
can be done instead with annotations
. In fact, it's now recommended that the marker interface pattern should not be used anymore. Annotations
can have parameters of various kinds, and they're much more flexible. We can also see that the examples used in Sun API’s
are rather old and that no new ones have been added since after introduce of Annotation
. In this post, we will see whether Marker Interfaces can still be used for any reasons.
Purpose of Marker Interfaces in Java
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.
marker interfaces list in java
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 - java.util.RandomAccess- support fast (generally constant time) random access
They are also known as tag interfaces since they tag all the derived classes
into a category based on their purpose
Difference between Interface and Marker Interface
Interface in general defines a contract. They represent a public
commitment and when implement
form a contract between the class
and the outside world. On the other hand, an empty interface
does not define any members, and as such, does not define a contract that can be implemented.
Normally, when a class implements an interface
, it tells something about the instances of the class
. It represent an "is a" relationship that exist in inheritance
. For example, when a class
implements List
, then object
is a List.
With marker interfaces, this inheritance
mechanism usually does not obey. For example, if class
implements the marker interface Serializable, then instead of saying that the object
is a Serializable
, we say that the object
has a property i.e. it is Serializable
.
Should Avoid Marker Interfaces?
One common problem occurs while using marker interfaces is that when a class
implements them, each subclasses inherit
them as well. Since you cannot unimplemented
an interface
in Java
, therefore a subclass
that does not want to treat differently will still be marked as Marker. For example, Foo implements Serializable, any subclass
Bar etc does too as well.
Moreover, there are places in the Sun API’s
where such interfaces
have been used for messy and varying purposes. Consider Cloneable Marker Interface. If the operation is not supported by an object
, it can throw an exception when such operation is attempted, like Collection.remove does when the collection does not support the remove operation (eg, unmodifiable collection) but a class
claiming to implement Cloneable and throwing CloneNotSupportedException from the clone() method wouldn't be a very friendly thing to do.
Many developers consider it as broken interface
. Ken Arnold and Bill Venners also discussed it in Java Design Issues. As Ken Arnold said,
If I were to be God at this point, and many people are probably glad I am not, I would say
deprecate
Cloneable
and have aCopyable
, becauseCloneable
has problems. Besides the fact that it's misspelled,Cloneable
doesn't contain theclone
method. That means you can't test if something is aninstance
ofCloneable
, cast it toCloneable
, and invokeclone
. You have to use reflection again, which is awful. That is only one problem, but one I'd certainly solve.
Oracle has also reported it as Bug which can refer at https://bugs.openjdk.java.net/browse/JDK-4098033
Are Marker Interfaces end?
Appropriate Use of Marker Interfaces vs Annotation
We usually hear that Marker Interface is now obsolete and it has no place. But, there are situations where they can be handy over using annotations.
Annotations
have to be checked at runtime
using reflection
. Empty interfaces
can be checked at compile-time
using the type system in the compiler
. Compile-time
checking can be one of the convincing reason to use such interfaces
.
Consider the example below:
@interface HasTag { } @HasTag public class ClasswithTag { } public void performAction(Object obj){ if (!obj.getClass().isAnnotationPresent(HasTag.class)) { throw new IllegalArgumentException("cannot perform action..."); } else { //do stuff as require } }
One problem with this approach is that the check for the custom attribute can occur only at runtime. Sometimes, it is very important that the check for the marker be done at compile-time
. Let me refine the above example to use Marker.
interface HasTag { } public class ClassWithTag implements HasTag { } public void performAction(HasTag ct){ //do stuff as require }
Similarly, in the case of the Serializable marker interface, the ObjectOutputStream.write(Object) method would fail at runtime if its argument does not implement the Interface
which would not be the case, if ObjectOutputStream
had a writeObject(Serializable)
method instead.
Marker Interfaces can also be well-integrated in Javadoc
where one can promptly see who implements marker interfaces or not by just look it up and see the list of implementing classes
.
Moreover, Joshua in Effective Java also recommends using Marker interface to define the type which can result in the very real benefit of compile-time
type checking.
Can we create our marker interface .if yes then can you tell me the practical use where custom marker interfaces can be used?
ReplyDelete