Marker Interfaces in Java
A courier sticks a red "FRAGILE" label on some parcels. The label has no instructions written on it; its presence alone changes how the parcel is handled. A marker interface is that label for a class: an interface with no methods at all. A class implements it only to say "I belong to this category", and other code checks for the marker with instanceof and behaves differently.
Markers in Action
public class Markers {
interface Fragile { }
static class Parcel {
final String item;
Parcel(String item) { this.item = item; }
}
static class GlassParcel extends Parcel implements Fragile {
GlassParcel(String item) { super(item); }
}
static class Sheet implements Cloneable {
String owner = "Navika";
Sheet copy() throws CloneNotSupportedException {
return (Sheet) clone();
}
}
static class Note {
Note copy() throws CloneNotSupportedException {
return (Note) clone();
}
}
public static void main(String[] args) {
Parcel[] parcels = { new Parcel("Books"), new GlassParcel("Vase") };
for (Parcel p : parcels) {
String label = p instanceof Fragile ? " [HANDLE WITH CARE]" : "";
System.out.println(p.item + label);
}
try {
System.out.println("Sheet copied for " + new Sheet().copy().owner);
new Note().copy();
} catch (CloneNotSupportedException e) {
System.out.println("Not cloneable: " + e.getMessage());
}
}
}Books
Vase [HANDLE WITH CARE]
Sheet copied for Navika
Not cloneable: Markers$NoteHow it works
Fragileis our own marker: an empty interface.GlassParcelimplements it, and the loop checks it withinstanceof.Sheet implements Cloneable, a marker from the JDK.Object.clone()checks for it, so copying aSheetworks.Notedoesn't implementCloneable. The very sameclone()call throwsCloneNotSupportedException. The marker alone changed the behavior.
Try it yourself: make Note implement Cloneable and run it again.
Markers in the JDK
| Marker | Who checks it | Effect |
|---|---|---|
java.io.Serializable | ObjectOutputStream | Objects can be written as bytes (serialization, later in the course); otherwise NotSerializableException |
java.lang.Cloneable | Object.clone() | Field-by-field copy allowed; otherwise CloneNotSupportedException |
java.util.RandomAccess | Algorithms in Collections | The list has fast index access (ArrayList has it, LinkedList doesn't), so index-based loops are used |
java.rmi.Remote | Java RMI | The object's methods can be called from another JVM |
Marker Interface or Annotation?
Annotations (covered later in the course) can also tag classes: @Deprecated, @FunctionalInterface. Which is better?
| Marker interface | Annotation | |
|---|---|---|
| Creates a type | Yes: you can write void ship(Fragile f) and the compiler checks it | No |
| Checked with | instanceof, at compile time and runtime | Reflection, at runtime (or an annotation processor) |
| Can carry data | No | Yes: @Retry(times = 3) |
| Can tag methods and fields | No, only classes | Yes |
| Inherited by subclasses | Always | Only if marked @Inherited |
Common Mistakes
Thinking Cloneable gives you a clone() method. It has none; it only switches on Object.clone(), which you still call and usually override.
Adding methods to a "marker". Then it's an ordinary interface, and every class must implement them.
Forgetting that markers are inherited. A subclass of a Serializable class is serializable too, wanted or not.
Interview Corner
What is a marker interface? Give examples.
A marker interface is an interface with no methods. Implementing it tags a class as having some property, and code checks it with instanceof. Examples are Serializable, which allows Java serialization; Cloneable, which allows Object.clone(); and RandomAccess, which signals fast index access in lists.
Marker interface vs annotation: which should you use?
A marker interface defines a type, so the compiler can enforce it, for example in a method parameter. An annotation can carry values, can be applied to methods and fields, and is read through reflection or annotation processing. Prefer a marker interface when type checking matters; prefer an annotation for metadata.
Practice
- Easy: Create a marker
Taxableand classesMedicineandElectronics, where only electronics are taxable. Print 18% tax only for taxable items. - Harder: Write
static void shipCarefully(Fragile item)and confirm that passing a plainParceldoesn't compile, while aGlassParceldoes.
Key Takeaways
Was this tutorial helpful?