What is a marker interface, and how is it used at runtime?
A marker interface is an interface with no methods at all. It carries no behaviour and declares no contract beyond the type itself, so its whole purpose is to tag a class. The type check is the interface, and the semantics come from what the code does when the check succeeds.
public class Main {
public static void main(String[] args) {
Order o = new Order();
System.out.println(describe(o));
}
static String describe(Object o) {
if (o instanceof Auditable) {
return "auditable record";
}
return "plain object";
}
}
interface Auditable { }
class Order implements Auditable { }The example tags an order as auditable and then checks for that tag at run time. The describe method returns a different result for a tagged object than for an untagged one, and the output shows the tagged branch being taken. No method had to be implemented for the tag to carry meaning.
The pattern has been used for decades. Serializable-like tags, a cacheable marker, a traceable marker. The idea is to let a general algorithm ask a question about an object without needing to know its concrete class.
The drawback is that the meaning of the tag is only in the head of whoever reads the code that checks for it. There is no method to document, no name that explains the behaviour, and nothing that tells you which classes are supposed to carry it. The class that implements the marker gains no visible capability.
That weakness is why annotations largely replaced markers. An annotation can carry metadata, is visible in the source at the point of use, and can be checked reflectively. The marker interface is still perfectly valid Java and still appears in older code and in a few frameworks, so it is worth recognising.