I would say, first of all, that Serializable and Cloneable are bad examples of marker interfaces. Of course, these are interfaces with methods, but they imply methods such as writeObject(ObjectOutputStream) . (The compiler will create a writeObject(ObjectOutputStream) method for you if you do not override it and all objects already have clone() , but the compiler will again create a real clone() method for you, but with caveats.) These are strange extreme cases that really don’t are good examples of design.)
Token interfaces are commonly used for one of two purposes:
1) As a shortcut, to avoid an excessively long type, which can happen with a large number of generics. For example, let's say you have this method signature:
public void doSomething(Foobar<String, Map<String, SomethingElse<Integer, Long>>>) { ... }
This is a dirty and annoying type, and, more importantly, difficult to understand. Instead, consider this:
public interface Widget extends Foobar<String, Map<String, SomethingElse<Integer, Long>>> { }
Then your method looks like this:
public void doSomething(Widget widget) { ... }
It is not only clearer, but now you can use the Javadoc the Widget interface, and it is also easier to search for all occurrences in your widget code.
2) Token interfaces can also be used as a path to the absence of Java intersection types. With the marker interface, you can require that something be of two different types, for example, in a method signature. Say you have an interface widget in your application as described above. If you have a method that requires a widget that also allows you to iterate over it (it invents, but works with me here), the only good solution is to create a marker interface that extends both interfaces:
public interface IterableWidget extends Iterable<String>, Widget { }
And in your code:
public void doSomething(IterableWidget widget) { for (String s : widget) { ... } }