One of the "clean" features of the Java programming language is that it mandates a separation between interfaces (pure behavior) and classes (state and behavior). Interfaces are used in Java to specify the behavior of derived classes.
Often you will come across interfaces in Java that have no behavior. In other words, they are just empty interface definitions. These are known as marker interfaces. Some examples of marker interfaces in the Java API include:
- java,lang.Cloneable
indicates that the objects clone method may be called
- java,io.Serializable
asserts that objects that implement it may be serialized using java.io.ObjectOutputStream.
- java.util.EventListener
is used for event listener classes
- javax.servlet.SingleThreadModel
states that this class should not be called for multiple threads concurrently
Marker interfaces are also called "tag" interfaces since they tag all the derived classes into a category based on their purpose. For example, all classes that implement the Cloneable interface can be cloned (i.e., the clone() method can be called on them). The Java compiler checks to make sure that if the clone() method is called on a class and the class implements the Cloneable interface. For example, consider the following call to the clone() method on an object o:
SomeObject o = new SomeObject();
SomeObject ref = (SomeObject)(o.clone());
If the class SomeObject does not implement the interface Cloneable (and Cloneable is not implemented by any of the superclasses that SomeObject inherits from), the compiler will mark this line as an error. This is because the clone() method may only be called by objects of type "Cloneable." Hence, even though Cloneable is an empty interface, it serves an important purpose.
Ken Arnold, who was/is behind several Java APIs at Sun, sounds off on marker interfaces
here, noting that they should rarely be used.
With the advent of annotations in Java 5 -which are a generic mechanism of adding metadata to a class-, marker interfaces have become obsolete, and no new ones should be defined.
Excerpt from Ken Arnold:I mentioned the term contract a couple times in this discussion. To me,
object design is a design of contracts. Contracts define what you are allowed to rely on.
Java has types as well as methods. There are contracts for entire types and contracts for methods. The
contract for the whole class or interface, then,
says if you implement this interface, you will have, in general, the following kinds of behaviors.
To me, a marker interface isn't wrong. It is a general case in the sense that it has no methods, so the whole contract is associated with the class and says what things of that type do. As a degenerate case, a marker interface probably shouldn't occur often. But on the other hand, there are times when a marker interface is a legitimate way to express that if you implement this interface, then you are have certain relationships.
Serializable might be a good example. None of the methods related to serialization belong as methods in the Serializable interface itself. For example, readObject should not be a public method in the Serializable interface. It is an implementation detail. At the same time,
Serializable is a behavioral contract that says you do expect your state shipped up in little bits and then those bits deconstructed into another copy of you. Serializable says that you have written the associated code to make sure serialization works right. So now I know I can use the object in a certain way--I can serialize and deserialize it. That is a real contract about an object that has a Serializable marker interface. I do think marker interfaces are rarely correct. But I don't think they are incorrect in principle.