Anmerkungen (auch als Metadaten bezeichnet) bieten uns eine formelle Möglichkeit, Informationen in unseren Code hinzuzufügen, sodass wir diese Daten zu einem späteren Zeitpunkt sehr bequem verwenden können.
1. Grundlegende Syntax
Java SE5 verfügt über drei integrierte Standardanmerkungen
@Override: Zeigt an, dass die aktuelle Methodendefinition die Methoden in der Superklasse überschreibt. Wenn Sie versehentlich die falsche Schreibweise buchstabieren oder die Methodensignatur nicht mit der überschriebenen Methode übereinstimmt, gibt der Compiler eine Fehlermeldung aus.
@Deprecated: Wenn der Programmierer ein kommentiertes Element verwendet, gibt der Compiler eine Warnmeldung aus
@Supperesswarnings: Schließen Sie die unangemessene Warnmeldung.
Java SE5 verfügt über vier eingebaute Meta-Anmerkungen
@Target: Gibt an, wo diese Annotation verwendet werden kann. Mögliche Elementtyp -Parameter umfassen:
1) Konstruktor: Die Aussage des Konstruktors
2) Feld: Domänenerklärung (einschließlich Enum -Instanzen)
3) Local_Variable: Lokale variable Deklaration
4) Methode: Methode Anweisung
5) Paket: Paketanweisung
6) Parameter: Parameterdeklaration
7) Typ: Klasse, Schnittstelle (einschließlich Annotationstyp) oder Enum -Deklaration
@Retention: Zeigt auf welcher Ebene an, um die Annotationsinformationen zu speichern. Zu den optionalen Parametern der Aufbewahrungspolizei gehören:
1) Quelle: Die Annotation wird vom Compiler verworfen
2) Klasse: Anmerkungen sind in Klassendateien verfügbar, werden jedoch vom VM verworfen
3) Laufzeit: VM wird auch während der Laufzeit Anmerkungen behalten, sodass die Annotationsinformationen durch den Reflexionsmechanismus gelesen werden können.
@Documented: Fügen Sie diese Annotation in Javadoc ein
@Inherited: Ermöglichen Sie Unterklassen, Annotationen in Elternklassen die meiste Zeit zu erben, Programmierer definieren hauptsächlich ihre eigenen Anmerkungen und schreiben ihre eigenen Prozessoren, um sie zu behandeln.
Usecase.java
Paket com; Import Java.lang.Annotation.Elementtype; importieren java.lang.annotation.retention; Import Java.lang.annotation.RetentionPolicy; importieren java.lang.annotation.target; @Target (elementtype.method) // Verwenden Sie, wo Ihre Annotation angewendet wird, und dies wird als Methode angewendet // Verwenden Sie, um auf welcher Ebene die Annotation im Quellcode (Klasse) oder Laufzeit (Laufzeit) @Retention (retentionPolicy.Runtime) public @Interface usecase {öffentlicher Int -ID () verfügbar ist. public String Beschreibung () Standard "Keine Beschreibung"; } PasswayUtils .java paket com; public class passwordUtils {@usecase (id = 47, Beschreibung = "Passwörter müssen mindestens einen numerischen") public boolean validatePassword () {return true; } @USecase (id = 48) public String EncryptPassword (String -Passwort) {Kennwort zurückgeben; } @USecase (id = 49, Beschreibung = "jong_cai") public void teamname () {System.out.println ("jong_cai"); }}
2. Schreiben Sie Annotation -Prozessor
Wenn es kein Werkzeug zum Lesen von Anmerkungen gibt, sind Anmerkungen nicht nützlicher als Anmerkungen. Bei der Verwendung von Anmerkungen besteht ein wichtiger Teil darin, Annotationsprozessoren zu erstellen und zu verwenden. Java SE5 erweitert die Reflexionsmechanismus -API, um Programmierern zu helfen, solche Werkzeuge zu konstruieren. Gleichzeitig bietet es auch ein externes Tool, das Programmierern dabei hilft, Java -Quellcode mit Anmerkungen anzualysieren. Im Folgenden finden Sie einen sehr einfachen Annotationsprozessor, mit dem wir die Kennwortutil -Klasse lesen und den Reflexionsmechanismus verwenden, um das @USecase -Tag zu finden. Wir geben es mit einer Reihe von ID -Werten und listet dann die in Passwordutils gefundenen Anwendungsfälle sowie die fehlenden Anwendungsfälle auf.
Usecasetracker.java Paket com; import Java.lang.reflect.Method; Import Java.util.ArrayList; Import Java.util.Collections; importieren java.util.list; öffentliche Klasse Usecasetracker {public static void Trackusecases (Liste <Integer> Liste, Klasse <?> cl) {für (Methode m: cl.getDeclaredMethods ()) {usecase us = m.getAnnotation (usecase.class); if (us! list.remove (New Integer (us.id ())); }} für (int i: list) {System.out.println ("WARNUNG: Fehlende Anwendungsfall-" + i); }} public static void main (String [] args) {list <GanzEger> list = new ArrayList <Integer> (); Collections.Addall (Liste, 47,48,49,50,51); TrackuSecases (Liste, passwordUtils.class); }}
Dieses Programm verwendet zwei Reflexionsmethoden: getDeclaredMethods () und getAnnotation (). Beide gehören zur kommentierten Schnittstelle (Klasse, Methode und Feld und andere Klassen implementieren diese Schnittstelle). Die Methode getAnnotation () gibt ein Annotationsobjekt des angegebenen Typs zurück, der Uscase ist. Wenn die kommentierte Methode keine Annotation des Typs hat, gibt sie einen Nullwert zurück. Dann extrahieren wir den Wert des Elements aus dem zurückgegebenen Usecase -Objekt, indem wir die Methoden ID () und Beschreibung () aufrufen. Die Methode "EncryptPassword () gibt den Beschreibungswert bei der Annotierung nicht an. Wenn der Prozessor seine entsprechende Annotation verarbeitet, wird der Standardwert der Methode Beschreibung () erhalten.
Die Annotation verbreitet sich in der Welt von Java. Wenn Sie Zeit haben, schreiben Sie diesen einfachen Anmerkungen. Es ist eine Einführung in die Annotation. Ich hoffe du kannst einen Ziegelstein werfen und zusammen lernen ...
Wenn Sie aufhören, Unsinn zu sprechen, ist das Üben das Endergebnis.
3. Beispiel
Sprechen wir zuerst über das Konzept der Annotation und dann darüber, wie Sie Ihre eigene Annotation entwerfen können.
Erstens öffnen Sie im Java.lang.Annotation -Paket, das mit JDK geliefert wird, die folgenden Quelldateien:
Quelldatei target.java
@Documented @Retention (retentionPolicy.Runtime) @target (elementtype.annotation_type) public @Interface target {elementtype [] value (); @Documented @Retention (retentionPolicy.Runtime) @target (elementtype.annotation_type) public @Interface target {elementtype [] value (); }
@Interface ist ein Schlüsselwort. Beim Entwerfen von Anmerkungen muss ein Typ als @Interface definiert werden, und Sie können keine Klassen- oder Schnittstellenschlüsselwörter verwenden (denken Sie, Sun ist ein bisschen geizig, aber er sieht der Benutzeroberfläche so ähnlich aus).
Quelldatei -Retention.java
@Documented @Retention (retentionPolicy.Runtime) @Target (elementtype.annotation_type) public @Interface -Retention {retentionPolicy value (); } @Documented @Retention (retentionPolicy.Runtime) @Target (elementtype.annotation_type) public @Interface -Retention {retentionPolicy value (); }
Nachdem Sie dies gesehen haben, sind Sie vielleicht vage und wissen nicht, wovon Sie sprechen. Mach dir keine Sorgen, schau mal. Die obigen Dateien verwenden die beiden Felder RetentionPolicy und Elementtype, und Sie können vermuten, dass dies zwei Java -Dateien sind. In der Tat sind die Quellcodes dieser beiden Dateien wie folgt:
Quelldatei RetentionPolicy.java
public enum retentionPolicy {Quelle, Klasse, Laufzeit} öffentliche Enum -RetentionPolicy {Quelle, Klasse, Laufzeit} Dies ist ein Enum -Typ mit drei Werten, nämlich Quelle, Klasse und Laufzeit.
Quelle bedeutet, dass die Annotationstypinformationen nur im Programmquellcode aufbewahrt werden. Wenn der Quellcode kompiliert wird, verschwinden die Annotationsdaten und werden nicht in der kompilierten .CLASS -Datei aufbewahrt.
Die Klasse bedeutet, dass die Annotationstypinformationen im Programmquellcode aufbewahrt werden und auch in der kompilierten .CLASS -Datei aufbewahrt werden. Bei der Ausführung werden diese Informationen nicht in die virtuelle Maschine (JVM) geladen. Beachten Sie, dass der Systemversandwert, wenn Sie keinen Aufbewahrungswert des Annotationstyps festlegen.
Die dritte ist die Laufzeit, was bedeutet, dass Informationen im Quellcode und im kompilierten .class -Datei beibehalten werden. Diese Informationen werden während der Ausführung in die JVM geladen.
Wenn beispielsweise die Aufbewahrung in @Override auf die Quelle eingestellt ist, benötigen Sie diese überprüften Informationen nicht. Im Gegenteil, die Aufbewahrung in @Deprecated ist auf die Laufzeit eingestellt, was bedeutet, dass Sie zusätzlich zur Warnung, welche Methode während der Zusammenstellung verwendet wird, auch überprüfen können, ob die Methode beim Ausführen veraltet ist.
Quelldateielementtype.java
public enum elementtype {type, feld, methode, parameter, konstruktor, local_variable, Annotation_type, paket} public enum elementtype {type, field, methode, parameter, konstruktor, local_variable, Annotation_type, Paket} @Das Elementtype im Ziel wird verwendet, um anzugeben, welche Elemente Annotationstyp verwendet werden kann. Erklären wir: Typ (Typ), Feld (Attribut), Methode (Methode), Parameter (Parameter), Konstruktor (Konstruktor), local_variable (lokale Variable), Annotation_Type, Paket (Paket), wobei Typ (Typ) sich darauf bezieht, dass sie an Klassen-, Schnittstellen-, Enum- und Annotationstypen verwendet werden.
Darüber hinaus ist aus dem Quellcode von 1 ersichtlich, dass @Target sich selbst benutzte, um sich selbst zu deklarieren und nur auf Annotation_Type verwendet werden zu können.
Wenn ein Annotationstyp nicht angibt, welche Elemente @Target verwendet werden, kann er in jedem Element verwendet werden, und das Element hier bezieht sich auf die oben genannten acht Typen.
Lassen Sie mich Ihnen ein paar korrekte Beispiele geben:
@Target (elementtype.method)
@Target (value = elementtype.method)
@Target (elementtype.method, elementtype.constructor)
Weitere Informationen finden Sie in der Javadoc -Dokumentation
Die Quelldateien verwenden alle @Documented. Der Zweck von @Documented besteht darin, diese Annotationstypinformationen im Dokument des Javaapi -Beschreibung anzuzeigen. Wenn nicht hinzugefügt wird, werden die von diesem Typ generierten Informationen nicht gefunden, wenn Javadoc zum Generieren des API -Dokuments verwendet wird.
Ein weiterer Punkt ist, dass Sie den Annotationstyp @inherited verwenden, wenn Sie Annotationsdaten in eine Unterklasse erben müssen.
Das Folgende ist das einfachste Annotationsbeispiel für das Design, das aus vier Dateien besteht.
Beschreibung.java
Paket leichter.javaeye.com; import Java.lang.Annotation.Documented; Import Java.lang.Annotation.Elementtype; importieren java.lang.annotation.retention; Import Java.lang.annotation.RetentionPolicy; importieren java.lang.annotation.target; @Target (elementtype.type) @Retention (retentionPolicy.Runtime) @Documented public @Interface Beschreibung {String value (); } paket leichter.javaeye.com; import Java.lang.Annotation.Documented; Import Java.lang.Annotation.Elementtype; importieren java.lang.annotation.retention; Import Java.lang.annotation.RetentionPolicy; importieren java.lang.annotation.target; @Target (elementtype.type) @Retention (retentionPolicy.Runtime) @Documented public @Interface Beschreibung {String value (); }
Hinweis: Alle Anmerkungen erben automatisch die Schnittstelle java.lang.annotation, sodass Sie keine anderen Klassen oder Schnittstellen erben können.
Der wichtigste Punkt ist, wie die Parameter im Annotationstyp festgelegt werden:
Erstens können Sie nur öffentliche oder Standard -Zugriffsrechte verwenden, um es zu ändern. Zum Beispiel String value (); Stellen Sie hier die Methode auf Standardstandtyp ein.
Zweitens können Parameterelemente nur acht grundlegende Datentypen verwenden: Byte-, Short-, Char-, Int-, Long-, Float-, Double-, Boolean- und Datentypen wie String, Enum, Klasse, Annotationen sowie Arrays dieser Typen. Zum Beispiel String value (); Das Parameterelement hier ist Zeichenfolge.
Drittens ist es am besten, den Parameternamen auf "Wert" zu setzen und anschließend Klammern hinzuzufügen, wenn es nur ein Parameterelement gibt. Beispiel: Das obige Beispiel hat nur ein Parameterelement.
Name.java
Paket leichter.javaeye.com; import Java.lang.Annotation.Documented; Import Java.lang.Annotation.Elementtype; importieren java.lang.annotation.retention; Import Java.lang.annotation.RetentionPolicy; importieren java.lang.annotation.target; // Beachten Sie, dass sich das @target hier von @Description unterscheidet und die Parametermitglieder auch unterschiedlich @Target (elementtype.method) @Retention (retentionPolicy.Runtime) @Documented public @Interface Name {String Originate (); String Community (); } paket leichter.javaeye.com; import Java.lang.Annotation.Documented; Import Java.lang.Annotation.Elementtype; importieren java.lang.annotation.retention; Import Java.lang.annotation.RetentionPolicy; importieren java.lang.annotation.target; // Beachten Sie, dass sich das @target hier von @Description unterscheidet und die Parametermitglieder auch unterschiedlich @Target (elementtype.method) @Retention (retentionPolicy.Runtime) @Documented public @Interface Name {String Originate (); String Community (); }
Javaeyer.java
Paket leichter.javaeye.com; @Description ("Javaeye, sei die beste Softwareentwicklungs -Austausch -Community") öffentliche Klasse Javaeyer {@Name (Originate = "Gründer: Robbin", Community = "Javaeye") public String getName () {return null; } @Name (Originate = "Gründer: Jiangnan Baiyi", Community = "Springside") public String getName2 () {return "liehen Sie zwei IDs von IDs aus, bitte vergib mir, dass ich dieses Beispiel geschrieben habe!"; }} paket leichter.javaeye.com; @Description ("Javaeye, sei die beste Softwareentwicklungs -Austausch -Community") öffentliche Klasse Javaeyer {@Name (Originate = "Gründer: Robbin", Community = "Javaeye") public String getName () {return null; } @Name (Originate = "Gründer: Jiangnan Baiyi", Community = "Springside") public String getName2 () {return "liehen Sie zwei IDs von IDs aus, bitte vergib mir, dass ich dieses Beispiel geschrieben habe!"; }}Schreiben Sie eine TestAnnotationsklasse, mit der die Informationen zum Extrakt Javaeyer ausgeführt werden können
Paket leichter.javaeye.com; import Java.lang.reflect.Method; import Java.util.hashset; Java.util.set importieren; public class testannotation { / *** Autor leichter* Hinweis: Details finden Sie in der Javadoc -Dokumentation für die Verwendung der Annotations -API* / public static void main (String [] args) Ausnahme {String class_name = "leichter.javaeye.com.javaeyer"; Class test = class.Forname (class_name); Methode [] method = test.getMethods (); boolesche Flagge = test.isAnnotationPresent (Beschreibung.CLASS); if (Flag) {Beschreibung Des = (Beschreibung) test.getAnnotation (Beschreibung.Class); System.out.println ("Beschreibung:"+des.Value ()); System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Hashset <Methode> () für (int i = 0; System.out.println ("erstellt:"+name.community ()); Annotation API*/ public static void main (String [] args) löst Ausnahme aus {String class_name = "leichter.javaeye.com.javaeyer"; Class test = class.Forname (class_name); Methode [] method = test.getMethods (); boolesche Flagge = test.isAnnotationPresent (Beschreibung.CLASS); if (Flag) {Beschreibung Des = (Beschreibung) test.getAnnotation (Beschreibung.Class); System.out.println ("Beschreibung:"+des.Value ()); System.out.println ("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- boolean floag = methode [i] .isannotationPresent (name.class); Auslaufergebnisse:
Beschreibung: Javaeye, die beste Gründerin der Softwareentwicklungs -Exchange -Community: Robbin erstellt Community: Javaeye Gründer: Javaeye Create Community: Springside