Markierungsschnittstellen kann man als Design-Pattern ansehen. Sie tauchen zwar nicht so häufig auf, doch Java kennt mit Serializable und Remote zwei prominente Vertreter.
Es anderes Beispiel soll hergestellt werden: Eine Textverarbeitung speichert in erster Linie Text. Dazu kommen noch weitere Datentypen wie Tabellen, Grafiken oder Formeln, aber wie der Name Textverarbeitung zeigt, ist der Datentyp im Kern Text. Etwas genauer betrachtet besteht der Text aus Seiten, Absätzen, Zeilen und Zeichen.
Frage: Nehmen wir an, dass die Textverarbeitung für jedes Zeichen ein Objekt vorsieht, welches in einer langen verketteten Liste gespeichert ist. Beim Eintippen neuer Buchstaben werden neue Objekte in die Liste eingefügt und beim Löschen entfernt. Stellt die Textverarbeitung eine Seite dar, wird die Liste sequentiell abgelaufen und jedes Element auf dem Bildschirm ausgegeben. Jedes ausgegebene Zeichen bekommt eine Position und diese wird laufend angepasst.
Zu den normalen druckbaren Zeichen wie Buchstaben und Ziffern kommen Sonderzeichen hinzu. Ein Objektmodell kann dann so aussehen, dass eine Schnittstelle notwendiges für alle Zeichen vorschreibt. Nennen wir die Schnittstelle WordCharacter und geben wir ihr die Methoden getChar(), getCharWidth(), getCharHeight() und drawChar(). Als Unterklassen könnte dann OrdinaryCharacter die druckbaren Zeichen behandeln und MetaCharacter die Sonderzeichen wie Tabulator, Leerzeichen, Return. Läuft ein Algorithmus zur Visualisierung durch die Datenstruktur, besorgt er sich jedes Zeichen, fragt wie lang es ist und ob es mit dem Wort noch in die Zeile passt. Wenn ja, wird die Zeichenposition auf der x-Achse um die Breite des Zeichens erweitert und das nächste Zeichen wird ausgegeben.
Ein Leerzeichen nimmt unter den Sonderzeichen eine besondere Stelle ein. Das liegt auch daran, dass der Leerraum unter Umständen noch erweitert wird, etwa beim Blocksatz. Dann kommt zu jeder Breite eines Leerzeichens noch zusätzlicher Weißraum dazu.
Wie wird die Textverarbeitung normale Zeichen und Leerzeichen verarbeiten, wenn eine Zeile ausgeben wird? Da Leerzeichen nichts auf dem Bildschirm ausgehen, sollen sie besonders behandelt werden.
Eine Lösung: Wenn in der Datenstruktur die Zeichen der Reihe nach vorliegen, wird man in einer Fallunterscheidung feststellen können, ob es sich um ein Leerzeichen handelt oder um anderes Zeichen.
für alle Zeichen einer Zeile Character c ist das aktuelle Element ist c.getChar() != ' ' dann verarbeite das Element weiter
Problem: Falls es nun weitere Elemente gibt, die eine ähnliche Sonderbehandlung haben wie das Leerzeichen, wird die Fallunterscheidung immer länger werden. Das wird sie auch, denn es gibt neben dem Standard-Leerzeichen noch weitere Zeichen, die für die Weißraum zuständig sind. Dazu zählt der Tabulator oder das nicht-trennende Leerzeichen. Wenn diese Fallunterscheidung auch noch an anderen Stellen eingesetzt wird, etwa beim Export der Daten in HTML, PDF, müssen die Entwickler darauf achten, Änderungen an der if-Anweisung auch konsistent an den anderen Stellen anzuwenden.
Pattern: Unsere bisherige Unterscheidung war nur auf Grund des Zeichencodes. Interessant ist, wenn das Leerzeichen noch einen weiteren Typ besitzt, denn wenn ein Weißraum-Objekt etwa den Typ WhitespaceChracter haben würde, ließe sich wiederum instanceof einsetzen, um herauszufinden, ob ein Zeichen-Objekt ein Leerzeichen ist oder nicht. Eine Fallunterscheidung mit vielen if-Anfragen fäll raus und es bleibt eine einfache instanceof-Abfrage. Alle Weißraum-Objekte legen wir dann so aus, dass sie einen speziellen Typ haben. Dazu kann ein Leerzeichen-Objekt eine Schnittstelle implementieren, die keine Funktionen vorschreibt.
Eine leere Schnittstelle nennt sich Marker-Interface oder Tag-Interface. Sie markiert ein Objekt mit einem Typ, der anschließend mit instanceof überprüft werden kann. In Java. Es gibt ein Java Marker-Interfaces an einigen Stellen. Die interessanteste Schnittstelle ist java.io.Serializable. Sie markiert alle Objekte, die über die Standardserialisierung automatisch geschrieben werden können. Eine Klasse, die nicht Serializabe ist, die aber trotzdem geschrieben werden soll, wird bei dem Serialisierungs-Vorgang einen Ausnahme melden.
Ein zweites Beispiel ist die Schnittstelle Remote. Sie wird benötigt, wenn Objekte über RMI verteilt angeboten werden sollen. Nur Objekte, die Remote implementieren werden RMI-fähig sein. Eine weitere Schnittstelle ist Clonable. Sie ermöglichst erst das Klonen von Objekten mit einer clone()-Funktion.
Seit Java 5 sind Annotationen eine Alternative zu Markierungsschnittstellen und daher seltener zu finden.