Standard-Annotationen
Annotationen dienen dazu, dem Übersetzer Mitteilungen zu machen, die sich auf die Art der Code-Generierung auswirken, ohne Einfluss auf die Semantik zu nehmen. Ein Programmfragment kann also in den meisten Fällen verstanden und mit dem selben Ergebnis ausgeführt werden, wenn auf die Annotationen verzichtet wird.
Zugriffsrechte
- ⟦private⟧: Nur dieses Objekt und die in seiner Objektdefinition enthaltenen Elemente dürfen auf ein derart annotiertes Element zugreifen.
- ⟦protected⟧: Nur dieses Objekt, die in seiner Objektdefinition enthaltenen Routinen und davon ableitende Objekte dürfen auf das derart annotierte Element zugreifen.
- ⟦package⟧: Nur Objekte aus dem selben Paket und die in deren Objektdefinition enthaltenen Elemente dürfen auf derart annotierte Elemente zugreifen.
- ⟦public⟧: Uneingeschränkter Zugriff möglich.
⟦privileged⟧: Der Zugriff ist gemäß der angegebenen Regeln möglich.
Annotationen für Objekte
- ⟦value⟧: Das Objekt soll als Werteobjekt implementiert werden.
- ⟦singleton⟧: Das Objekt soll als Solitär (Singleton) implementiert werden.
- ⟦program⟧: Das Objekt ist ein Progamm.
- ⟦open⟧: Bei dem Objekt handelt es sich um eines, von dem abgeleitet werden darf.
⟦meta⟧: Bei dem Objekt handelt es sich um ein Meta-Objekt, also eine Klasse.
Annotationen für Elemente
- ⟦abstract⟧: Das Element existiert nicht und einem ableitenden Objekt ist es überlassen, eine passende Implementierung dafür zu liefern.
- ⟦override⟧: Das Element überschreibt in einem ableitenden Objekt eines, das überschrieben werden darf, also mit ⟦abstract⟧ oder ⟦open⟧ annotiert ist.
- ⟦native⟧: Das Element ist spezifisch für die zugrunde liegende Plattform und muss dementsprechend von dieser vorgegeben werden. Dies findet in der Regel über das Superclass-Renaming statt.
⟦static⟧: Gibt an, dass der Wert dieses Elements bereits zur Übersetzungszeit bekannt ist.
Annotationen für Felder
⟦immutable⟧: Auf das Feld selbst und auf das referenzierte Objekt kann nur lesend zugegriffen werden.
Annotationen für Routinen
- ⟦test⟧: Die Routine darf nur im Zusammenhang mit Tests verwendet werden.
- ⟦inline⟧: Die Routine soll möglichst „textuell“ eingesetzt werden.
- ⟦abstract⟧: Die Routine existiert nicht und einem ableitenden Objekt ist es überlassen, eine passende Implementierung dafür zu liefern.
- ⟦override⟧: Gibt an, dass es sich bei einer derart annotierten Routine um eine handelt, die bei einem ableitenden Objekt die ursprüngliche Routine ersetzt.
- ⟦default⟧: Eine im Grunde abstrakte Methode, die eine Standard-Implementierung liefert.
- ⟦nondeterministic⟧: Gibt an, dass die so annotierte Routine einen nicht vorhersehbaren, insbesondere auch bei Funktionen bei gleichen Argumenten nicht den selben Wert liefert.
- ⟦mirrors⟧: Gibt diejenige Funktion an, die das selbe Ergebnis dieser annotierten Funktion liefert, wenn man dazugehörige Operatorsymbol spiegelt und die Parameter vertauscht.
⟦negates⟧: Gibt diejenige Funktion an, die das negierte Ergebnis dieser annotierten Funktion liefert.
Annotationen für Funktionen
- ⟦pure⟧: Eine derart annotierte Funktion wird als pur verstanden. Damit kann sie nach Belieben sofort oder verzögert ausgewertet, umsortiert und deren Ergebnisse zwischengespeichert werden.
⟦cache⟧: Die Werte einer Funktion sollen gespeichert werden, damit zukünftige Aufrufe mit den selben Parametern nur abgerufen und nicht neu berechnet werden.
Annotationen für Methoden
- ⟦function⟧: Bei der annotierten Methode handelt es sich um eine, die wie eine echte Funktion keine Nebeneffekte hat. Diese Annotation ist bei Wertobjekten nicht nötig, weil dort alle ex definitione keine Nebeneffekte haben können. Damit unterliegen diese Methoden auch nicht mehr den Einschränkungen der Evaluierungsreihenfolge und deren Ergebnisse können zur Wiederverwendung zwischengespeichert werden. Dementsprechend ist hier Vorsicht geboten, wenn derart annotierte Methoden zur Überschreibung offen sind.
- ⟦procedure⟧: Bei der annotierten Methode handelt es sich um eine, die wie eine Prozedur Nebeneffekte haben kann, aber das Objekt selbst unverändert lässt. Diese Annotation soll insbesondere bei Wertobjekten dokumentieren, dass die markierte Methode Nebeneffekte (Ausgabe von Meldungen, Manipulation eines globalen Zustands etc.) hat.
- ⟦convenience⟧: Bei der annotierten Methode handelt es sich um eine, die allenfalls die Argumente der Routine manipuliert, um eine Routine aufzurufen, die nicht nur der Bequemlichkeit wegen existiert. Typischerweise handelt es sich um eine überladene Methode, die für einen dedizierten Anwendungsfall spezialisiert wurde.
- ⟦open⟧: Bei der Methode handelt es sich um eine, die überschrieben werden darf.
- ⟦final⟧: Die Methode darf nicht (mehr) überschrieben werden.
- ⟦getter⟧: Markiert eine Methode als Implementierung für einen Lesezugriff eines (virtuellen) Feldes (field) gleichen Namens.
⟦setter⟧: Markiert eine Methode als Implementierung für einen Schreibzugriff eines (virtuellen) Feldes (field) gleichen Namens.
Annotationen für Routinenparameter und -argumente
- ⟦lazy⟧: Das an diesen Parameter übergebene Element wird nur dann und frühestens dann ausgewertet, wenn es (zum ersten Mal) benötigt wird.
- ⟦var⟧: Die an diesen Parameter übergebene Variable kann in der Routine als solche manipuliert werden.
⟦ref⟧: Der an diesen Parameter übergebene Wert, wird als Referenz übergeben. Dies betrifft allerdings nur den Übergabemechanismus; der übergebene Wert selbst kann nicht verändert werden.
Dabei müssen die Annotationen ⟦lazy⟧ und ⟦var⟧ auch beim Aufruf angegeben werden, damit der Leser den Nebeneffekt „sehen“ kann, ohne die Funktionssignatur kennen zu müssen.
Annotationen für Anweisungen
Annotationen für Schleifen
- ⟦enroll⟧: Veranlasst, dass die so annotierte Schleife durch die korrespondierende lineare Sequenz von Anweisungen ersetzt wird (vorausgesetzt, dass alle beteiligten Komponenten zur Übersetzungszeit bestimmt werden können).
⟦endless⟧: Die annotierte Schleife ist wunschgemäß eine Endlosschleife.
Annotationen für Bedingungen
- ⟦probable⟧: Gibt an, dass die derart annotierte Bedingung höchstwahrscheinlich erfüllt ist.
⟦improbable⟧: Gibt an, dass die derart annotierte Bedingung höchstwahrscheinlich nicht erfüllt ist.
Annotationen für Verzweigungstabellen
- ⟦nondeterministic⟧: Gibt an, dass alle Bedingungen geprüft werden und bei Erfolg ein beliebiger Zweig aus den erfüllten Bedingungen ausgewählt wird.
- ⟦binarysearch⟧: Gibt an, dass die gegebenen n Bedingungen derart sortiert werden, dass über eine binäre Suche höchstens O(log n) Prüfungen nötig sind.
- ⟦tablesearch⟧: Gibt an, dass die gegebenen n Bedingungen über eine Sprungtabelle organisiert werden sollen, damit höchstens O(1) Prüfungen nötig sind.
- ⟦linearsearch⟧: Gibt an, dass die gegebenen Bedingungen in der angegebenen Reihenfolge (mit einem Aufwand von O(n)) geprüft werden sollen.
- ⟦hashsearch⟧: Gibt an, dass die Suche über eine (dedizierte) Streuwertfunktion (Hash-Funktion) erfolgen soll.
- ⟦complete⟧: Gibt an, dass die aufgelisteten Fälle vollständig sind und ein davon abweichender Fall bei einer Neuübersetzung zu einem Fehler und zur Laufzeit zu einer Ausnahme führt.
⟦incomplete⟧: Gibt an, dass die aufgelisteten Fälle unvollständig sind und ein davon abweichender Fall nicht behandelt werden muss.
Annotationen für Aufzählungen
Annotationen für die Elemente
⟦default⟧: Gibt bei einer Aufzählung von Elementen an, welches der Standardwert ist, der bei einer impliziten Initialisierung genutzt wird.
Annotationen für die Aufzählung
- ⟦ordered⟧: Die Elemente der Aufzählung sind wie angegeben geordnet.
- ⟦flags⟧: Die Elemente der Aufzählung können unter dem angegebenen Typ auch kombiniert genutzt werden