Zu den Neuerungen in Java 5 gehören Annotations. Der JSR 175 beschreibt Annotations als "Metadata Facility for the Java Programming Language".
Annotationen beinhalten Metadaten, also Daten über andere Daten. Zu vielen Java-Programmelementen können Annotationen hinzugefügt werden, die während des Build-Vorgangs oder auch zur Laufzeit ausgewertet werden können.
Auch vor Java 5 gab es bereits Annotationen-ähnliche Metadaten:
/** * @deprecated * @see #meineNeueMethode */ void meineVeralteteMethode() { ... }
Vor Java 5 mussten Annotationen-ähnliche Metadaten zum Beispiel in JavaDoc-Kommentaren untergebracht werden. Einige wurden vom Compiler ausgewertet (z.B. @deprecated). Andere wurden durch Zusatztools ausgewertet (z.B. mit XDoclet).
Das gleiche Beispiel sieht mit der neuen Java-5-@Deprecated-Annotation folgendermaßen aus:
/** * @see #meineNeueMethode */ @Deprecated void meineVeralteteMethode() { ... }
Java-5-Annotationen beginnen mit dem '@'-Zeichen und werden vor dem Programmelement, auf das sie sich beziehen, plaziert, üblicherweise vor den anderen Modifizierern (public, static, final, abstract, void, ...).
Es gibt drei Annotation-Kategorien:
Kategorie | Erläuterung | Beispiele für Anwendung und Deklaration |
---|---|---|
Marker Annotation | Es wird kein Parameter übergeben. Die Annotation dient zur Markierung. Beispiele: @Deprecated, @Override |
// Anwendung: @MyAnnotation // Deklaration: public @interface MyAnnotation {} |
Single Member Annotation | Eine Annotation mit nur einem Parameter. Dieser Parameter hat den Parameternamen "value", der aber beim Annotieren nicht angegeben werden muss. Falls für den Parameter ein Defaultwert definiert ist, kann die Annotation auch ohne Parameter verwendet werden. Der eine Parameter kann ein Array von mehreren Parametern sein. Beispiele: @Retention, @Target |
// Anwendung: @MyAnnot( myValue ) // Deklaration: public @interface MyAnnot { String value(); } |
Normal Annotation | Eine Annotation mit möglicherweise mehreren Parametern. Den Parametern muss jeweils der Parametername vorangestellt werden. Alle Parameter, für die die Deklaration keinen Defaultwert vorsieht, müssen gesetzt werden. Beispiele: @MeineNeueAnnotation, @Resource |
// Anwendung: @MyAnnot( prm1=val1, prm2=val2 ) // Deklaration: public @interface MyAnnot { double prm1(); String prm2(); } |
Meta-Annotationen sind Annotationen, die auf Annotationen angewendet werden können. Einige Meta-Annotationen können sowohl auf Annotationen als auch auf andere Programmelemente angewendet werden, andere nur ausschließlich auf Annotationen.
Ein Softwareentwickler, der normalerweise nur bestehende Annotationen anwendet, wird nicht direkt Meta-Annotationen verwenden. Trotzdem muss er sie kennen, um die Deklaration der Java-Annotationen, die er anwenden will, zu verstehen.
Die beiden folgenden besonders wichtigen Meta-Annotationen können nur ausschließlich auf Annotationen angewendet werden:
@Retention |
@Retention (übersetzt "Bewahrung") steuert die Beibehaltung und Verfügbarkeit der Annotation-Informationen,
also wie lange die Annotation-Informationen erhalten bleiben. Dazu wird einer der folgenden Werte übergeben (Beispiel folgt weiter unten):
| ||||||||||||||||
@Target | @Target (übersetzt "Ziel") steuert welche Programmelemente annotiert werden können. Dazu wird einer oder mehrere der folgenden Werte übergeben:
|
Normalerweise werden vorhandene Annotationen auf den eigenen Code angewendet. Vorher müssen die Annotationen deklariert worden sein und nachher müssen sie ausgewertet werden. Obwohl die beiden letzteren Tätigkeiten seltener (oder nie) explizit vom Entwickler programmiert werden, werden im Folgenden alle drei Schritte kurz beschrieben, weil so am leichtesten die Funktion verstanden werden kann.
Für die Deklaration einer Annotation wird das Schlüsselwort "@interface" verwendet und die Parameter werden als parameterlose Methoden deklariert.
Das Beispiel deklariert eine "Normal Annotation", also einer Annotation mit mehreren Parametern.
Damit die Annotation nicht nur zur Build-Zeit, sondern auch später zur Laufzeit zur Verfügung steht, wird eine Meta-Annotation auf die neue Annotation angewendet, nämlich "@Retention(RetentionPolicy.RUNTIME)":
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention( RetentionPolicy.RUNTIME ) public @interface MeineNeueAnnotation { int meinIntParameter(); String meinStringParameter(); String meinDefaultParameter() default "xyz"; String[] meinArrayParameter(); }
In der folgenden Minibeispielklasse wird die Annotation angewendet. Der Defaultparameter braucht nicht gesetzt zu werden, aber das Fehlen eines anderen Parameters würde zu einem Compilerfehler führen. Bitte beachten Sie die Syntax mit geschweiften Klammern für den Array-Parameter ("meinArrayParameter = { ..., ... }").
public class AnwendungMitAnnotation { @MeineNeueAnnotation( meinIntParameter=42, meinStringParameter="Blubb", meinArrayParameter={"a","b","c"} ) public void meineMethodeMitAnnotation() { //... } }
Folgende Anwendung liest die übergebenen Parameter der Annotation zur Laufzeit aus (inklusive des Defaultparameters):
import java.lang.reflect.Method; public class AnnotationZurLaufzeitVerwenden { public static void main( String[] args ) throws Exception { Method[] methods = AnwendungMitAnnotation.class.getMethods(); for( Method m : methods ) { if( m.isAnnotationPresent( MeineNeueAnnotation.class ) ) { MeineNeueAnnotation a = m.getAnnotation( MeineNeueAnnotation.class ); System.out.println( "Methode: " + m.getName() ); System.out.println( "meinIntParameter(): " + a.meinIntParameter() ); System.out.println( "meinStringParameter(): " + a.meinStringParameter() ); System.out.println( "meinDefaultParameter(): " + a.meinDefaultParameter() ); System.out.println( "meinArrayParameter()[0]: " + a.meinArrayParameter()[0] ); System.out.println( "meinArrayParameter()[1]: " + a.meinArrayParameter()[1] ); System.out.println( "meinArrayParameter()[2]: " + a.meinArrayParameter()[2] ); } } } }
Im Beispiel wird Reflection verwendet. Eine Alternative wäre AOP (Aspect oriented Programming).
Speichern Sie die drei .java-Dateien und führen Sie folgende Kommandozeilenbefehle aus:
javac *.java
java AnnotationZurLaufzeitVerwenden
Das Ergebnis sieht so aus:
Methode: meineMethodeMitAnnotation meinIntParameter(): 42 meinStringParameter(): Blubb meinDefaultParameter(): xyz meinArrayParameter()[0]: a meinArrayParameter()[1]: b meinArrayParameter()[2]: c
Package java.lang.annotation (Meta-Annotationen, also Annotationen, die nur auf Annotationen angewendet werden können (definiert durch "@Target(ANNOTATION_TYPE)")) | ||||||||||||||||||||
Annotation | Erläuterung | Deklaration | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@Documented | Steuert JavaDoc-Dokumentationen. | @Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface Documented | ||||||||||||||||||
@Inherited | Steuert die Vererbbarkeit der Annotation. | @Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface Inherited | ||||||||||||||||||
@Retention | @Retention (übersetzt "Bewahrung") steuert die Beibehaltung und Verfügbarkeit der Annotation-Informationen
(--> Beispiel).
|
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface Retention | ||||||||||||||||||
@Target | @Target steuert welche Programmelemente annotiert werden können.
|
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface Target | ||||||||||||||||||
Package java.lang | ||||||||||||||||||||
Annotation | Erläuterung | Deklaration | ||||||||||||||||||
@Deprecated | Markiert Programmelemente, die nicht mehr verwendet werden sollen. | @Documented @Retention(RUNTIME) public @interface Deprecated | ||||||||||||||||||
@Override | Markiert Methoden, die eine Methode der Superklasse überschreiben. Dies ist sinnvoll zur Dokumentation und damit sonst schwer zu findende Tippfehler vom Compiler gefunden werden. |
@Target(METHOD) @Retention(SOURCE) public @interface Override | ||||||||||||||||||
@SuppressWarnings | Unterdrückt einzelne oder mehrere Warnmeldungen. (Benötigte Annotationen können z.B. in Eclipse über 'Strg + 1' automatisch eingefügt werden.) |
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(SOURCE) public @interface SuppressWarnings | ||||||||||||||||||
Package javax.annotation | ||||||||||||||||||||
@Resource | Markiert eine allgemeine Ressource (z.B. SessionContext, DataSource, UserTransaction), die injiziert werden soll (--> Beispiel). | |||||||||||||||||||
Package javax.annotation.security | ||||||||||||||||||||
@RolesAllowed | Spezifiziert die Rollen, die Zugriff zu einer Klasse oder Methode haben. | |||||||||||||||||||
Package javax.ejb | ||||||||||||||||||||
@EJB | Indiziert eine Abhängigkeit zu einer Local- oder Remote-EJB (--> Beispiel). | |||||||||||||||||||
@Local | Deklariert das Business Interface einer Session Bean als Local-sichtbar. | |||||||||||||||||||
@Remote | Deklariert das Business Interface einer Session Bean als Remote-sichtbar (--> Beispiel). | |||||||||||||||||||
@Stateful | Kennzeichnet die Klasse als Stateful Session Bean. | |||||||||||||||||||
@Stateless | Kennzeichnet die Klasse als Stateless Session Bean (--> Beispiel). | |||||||||||||||||||
@TransactionAttribute | Setzt die Transaction Propagation einer Klasse oder Methode:
| |||||||||||||||||||
@TransactionManagement | Angabe der Transaktionssteuerung:
| |||||||||||||||||||
Package javax.persistence | ||||||||||||||||||||
@Basic | Daten zu einem Feld, z.B. EAGER / LAZY. | |||||||||||||||||||
@Column | Daten zu einem Feld, z.B. expliziter Spaltenname, maximale Länge, Nullable (--> Beispiel). | |||||||||||||||||||
@DiscriminatorColumn | Discriminator-Spalte, falls InheritanceType = SINGLE_TABLE oder JOINED (siehe auch Vererbung/Polymorphie). | |||||||||||||||||||
@Entity | Spezifiziert eine Klasse als Entity Bean (--> Beispiel, anderes Beispiel). | |||||||||||||||||||
@GeneratedValue | Spezifiziert einen Primary-Key-Generator (--> Beispiel, anderes Beispiel). | |||||||||||||||||||
@Id | Spezifiziert den Primary Key (--> Beispiel, anderes Beispiel). | |||||||||||||||||||
@Inheritance | Bestimmt die Abbildungsstrategie einer Klassenhierarchie auf eine Menge von Datenbanktabellen. | |||||||||||||||||||
@Lob | Large Object (BLOB oder CLOB). | |||||||||||||||||||
@ManyToMany | Definiert eine M:N-Relation. | |||||||||||||||||||
@ManyToOne | Definiert eine N:1-Relation. | |||||||||||||||||||
@OneToMany | Definiert eine 1:N-Relation. | |||||||||||||||||||
@OneToOne | Definiert eine 1:1-Relation. | |||||||||||||||||||
@OrderBy | Sortierung. | |||||||||||||||||||
@PersistenceContext | Injiziert einen EntityManager. | |||||||||||||||||||
@PersistenceUnit | Injiziert eine EntityManagerFactory (--> Beispiel). | |||||||||||||||||||
@SequenceGenerator | Parametriert den Primärschlüsselgenerator auf Sequenzbasis. | |||||||||||||||||||
@Table | Definiert den Tabellennamen für die Entity Bean (--> Beispiel). | |||||||||||||||||||
@Transient | Definiert nicht zu persistierende Felder. | |||||||||||||||||||
@UniqueConstraint | Definition einer Eindeutigkeitsbedingung für eine Spalte. | |||||||||||||||||||
@Version | Versionsspalte für Optimistic Locking. | |||||||||||||||||||
Package javax.management | ||||||||||||||||||||
@MXBean | Deklaration einer MXBean. | |||||||||||||||||||
Package javax.jws | ||||||||||||||||||||
@WebService | Deklariert eine Klasse oder ein Interface als Webservice. | |||||||||||||||||||
@WebMethod | Setzt zusätzliche Eigenschaften für Methoden, die als Webservice-Operation exportiert werden sollen. |
Java SE 7
Unter den folgenden Links finden Sie zu den Java-SE-Packages jeweils unter der Überschrift "Annotation Types Summary" Annotation-Listen:
java.lang.annotation, java.lang, java.beans, javax.annotation, javax.annotation.processing, javax.jws, javax.jws.soap, javax.management, javax.xml.bind.annotation.adapters, javax.xml.bind.annotation, javax.xml.ws.
Java EE 7
Unter den folgenden Links finden Sie zu den Java-EE-Packages jeweils unter der Überschrift "Annotation Types Summary" Annotation-Listen (einige Annotationen sind sowohl in Java SE als auch in Java EE enthalten):
javax.annotation, javax.annotation.security, javax.ejb, javax.interceptor, javax.jws, javax.jws.soap, javax.persistence, javax.xml.bind.annotation.adapters, javax.xml.bind.annotation, javax.xml.ws.