Annotation (Java): Unterschied zwischen den Versionen
K (1 Versionen) |
K (→Annotation definieren) |
||
(9 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 9: | Zeile 9: | ||
Verglichen mit einem Interface hat eine Annotation folgende Unterschiede: | Verglichen mit einem Interface hat eine Annotation folgende Unterschiede: | ||
* Dem Schlüsselwort "interface" wird ein @ vorangestellt. | * Dem Schlüsselwort "interface" wird ein @ vorangestellt. | ||
− | * Lediglich Methoden ohne Argumente und ohne [[Exception_(Java)|throws-Klauseln]] sind erlaubt | + | * Lediglich [Methode|Methoden]] ohne Argumente und ohne [[Exception_(Java)|throws-Klauseln]] sind erlaubt |
− | * Rückgabewert der Methoden dürfen alle [[Primitiv_(Java)|primitiven Datentypen]], [[String_(Java_API)|String]], [[Class_(Java_API)|Class]], [[Enumeration_(Java)|Enumerationen]], Annotationen und [[Array_(Java)|Arrays]] der eben | + | * Rückgabewert der Methoden dürfen alle [[Primitiv_(Java)|primitiven Datentypen]], [[String_(Java_API)|String]], [[Class_(Java_API)|Class]], [[Enumeration_(Java)|Enumerationen]], Annotationen und [[Array_(Java)|Arrays]] der eben genannten sein. |
* Methoden können einen "default"-Wert besitzen. | * Methoden können einen "default"-Wert besitzen. | ||
Ein Beispiel: | Ein Beispiel: | ||
− | < | + | <syntaxhighlight lang="java" line='line'> |
@Retention( RetentionPolicy.RUNTIME ) | @Retention( RetentionPolicy.RUNTIME ) | ||
@Target( ElementType.METHOD ) | @Target( ElementType.METHOD ) | ||
Zeile 22: | Zeile 22: | ||
int start() default 1; | int start() default 1; | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
Die hier definierte Annotation ''IntegerSetter'' besitzt drei Elemente: "min", "max" und "start". Alle drei sind vom Typ "int". Das Element "start" besitzt einen Default-Wert von 1. | Die hier definierte Annotation ''IntegerSetter'' besitzt drei Elemente: "min", "max" und "start". Alle drei sind vom Typ "int". Das Element "start" besitzt einen Default-Wert von 1. | ||
Zeile 31: | Zeile 31: | ||
Beispiel: | Beispiel: | ||
− | < | + | <syntaxhighlight lang="java">public class Point { |
private int x, y; | private int x, y; | ||
Zeile 47: | Zeile 47: | ||
list( Point.class ); | list( Point.class ); | ||
} | } | ||
− | }</ | + | } |
+ | </syntaxhighlight> | ||
Hier werden die beiden Methoden "setX" und "setY" mit ''IntegerSetter'' markiert. Da das Element "start" einen Default-Wert besitzt, ist es nicht notwendig, das Element jedesmal neu zu definieren. | Hier werden die beiden Methoden "setX" und "setY" mit ''IntegerSetter'' markiert. Da das Element "start" einen Default-Wert besitzt, ist es nicht notwendig, das Element jedesmal neu zu definieren. | ||
Zeile 54: | Zeile 55: | ||
Beispiel: | Beispiel: | ||
− | < | + | <syntaxhighlight lang="java" line='line'> |
+ | public static void main( String[] args ) throws Exception{ | ||
list( Point.class ); | list( Point.class ); | ||
} | } | ||
Zeile 69: | Zeile 71: | ||
} | } | ||
} | } | ||
− | }</ | + | } |
+ | </syntaxhighlight> | ||
Die Ausgabe dieses Programmes ist: | Die Ausgabe dieses Programmes ist: | ||
<pre>setX: min=0, max=5, start=1 | <pre>setX: min=0, max=5, start=1 | ||
Zeile 81: | Zeile 84: | ||
== java.lang == | == java.lang == | ||
− | {| | + | {| {{Prettytable}} |
! width="20%" | Name | ! width="20%" | Name | ||
! width="80%" | Zweck | ! width="80%" | Zweck | ||
Zeile 93: | Zeile 96: | ||
| @Override | | @Override | ||
| Markiert eine Methode, die eine andere Methode [[Überschreiben_(Java)|überschreibt]]. Ein Compiler kann dank dieser Annotation sicher sein, dass der Programmierer eine Methode absichtlich überschrieben hat. | | Markiert eine Methode, die eine andere Methode [[Überschreiben_(Java)|überschreibt]]. Ein Compiler kann dank dieser Annotation sicher sein, dass der Programmierer eine Methode absichtlich überschrieben hat. | ||
+ | |- | ||
|} | |} | ||
== java.lang.annotation == | == java.lang.annotation == | ||
− | {| | + | {| {{Prettytable}} |
! width="20%" | Name | ! width="20%" | Name | ||
! width="80%" | Zweck | ! width="80%" | Zweck | ||
Zeile 110: | Zeile 114: | ||
Beispiel: Eine Annotation die für Methoden und Typen verwendet werden kann: | Beispiel: Eine Annotation die für Methoden und Typen verwendet werden kann: | ||
− | < | + | <syntaxhighlight lang="java" line='line'> |
+ | @Target( {ElementType.TYPE, ElementType.METHOD} ) | ||
public @interface Something{ | public @interface Something{ | ||
... | ... | ||
− | }</ | + | } |
+ | </syntaxhighlight> | ||
|- | |- | ||
Zeile 121: | Zeile 127: | ||
| @Inherited | | @Inherited | ||
| Markiert eine Annotation, welche vererbt werden soll. Damit ist gemeint: wenn die Annotation eine [[Klasse_(Java)|Klasse]] markiert, sind automatisch alle Unterklassen ebenfalls markiert. | | Markiert eine Annotation, welche vererbt werden soll. Damit ist gemeint: wenn die Annotation eine [[Klasse_(Java)|Klasse]] markiert, sind automatisch alle Unterklassen ebenfalls markiert. | ||
+ | |- | ||
|} | |} | ||
[[Kategorie:Java]] | [[Kategorie:Java]] | ||
+ | [[Kategorie:Java Grundlagen]] |
Aktuelle Version vom 8. März 2018, 20:05 Uhr
In Java kann mit einer Annotation Metainformation in den Quellcode eines Programmes eingefügt werden.
Annotation können von unterschiedlichsten Tools ausgelesen werden. So kann bereits ein Compiler einige Annotationen verwenden, z.B. um Warnungen zu unterdrücken oder zu generieren.
Inhaltsverzeichnis
Eigene Annotationen
Es ist möglich, eigene Annotationen zu schreiben. Der Syntax einer Annotation gleicht dem Syntax eines Interfaces. Wie ein Interface muss auch eine Annotation in einer eigenen Java-Datei gespeichert werden.
Annotation definieren
Verglichen mit einem Interface hat eine Annotation folgende Unterschiede:
- Dem Schlüsselwort "interface" wird ein @ vorangestellt.
- Lediglich [Methode|Methoden]] ohne Argumente und ohne throws-Klauseln sind erlaubt
- Rückgabewert der Methoden dürfen alle primitiven Datentypen, String, Class, Enumerationen, Annotationen und Arrays der eben genannten sein.
- Methoden können einen "default"-Wert besitzen.
Ein Beispiel:
1 @Retention( RetentionPolicy.RUNTIME )
2 @Target( ElementType.METHOD )
3 public @interface IntegerSetter {
4 int min();
5 int max();
6 int start() default 1;
7 }
Die hier definierte Annotation IntegerSetter besitzt drei Elemente: "min", "max" und "start". Alle drei sind vom Typ "int". Das Element "start" besitzt einen Default-Wert von 1.
Retention und Target sind andere Annotationen, welche eine Aussage über den Gültigkeitsbereich der Annotation IntegerSetter machen. Hier wird gesagt, dass die Annotation IntegerSetter zur Laufzeit sichtbar ist, und nur für Methoden verwenden werden kann.
Annotation anwenden
Annotationen werden vor das zu markierende Element geschrieben, einfach indem nach einem @ der Name der Annotation ausgeschrieben wird. Falls die Annotation Elemente besitzt, müssen die Elemente noch gesetzt werden. Dazu schreibt man, in runden Klammern, "Element = Wert"-Paare.
Beispiel:
public class Point {
private int x, y;
@IntegerSetter( min=0, max=5 )
public void setX( int x ){
this.x = x;
}
@IntegerSetter( min=0, max=20, start=5 )
public void setY( int y ){
this.y = y;
}
public static void main( String[] args ) throws Exception{
list( Point.class );
}
}
Hier werden die beiden Methoden "setX" und "setY" mit IntegerSetter markiert. Da das Element "start" einen Default-Wert besitzt, ist es nicht notwendig, das Element jedesmal neu zu definieren.
Annotation zur Laufzeit auslesen
Selbstgeschriebene Annotation werden oft zur Laufzeit benötigt. Mit Reflection können die Annotation ausgelesen werden. Die meisten Reflection-Klassen bieten eine entsprechende Methode "getAnnotation(s)"
Beispiel:
1 public static void main( String[] args ) throws Exception{
2 list( Point.class );
3 }
4
5 public static void list( Class<?> clazz ) throws Exception{
6 for( Method method : clazz.getMethods() ){
7 IntegerSetter value = method.getAnnotation(
8 IntegerSetter.class );
9 if( value != null ){
10 System.out.printf(
11 "%s: min=%d, max=%d, start=%d\n",
12 method.getName(), value.min(),
13 value.max(), value.start() );
14 }
15 }
16 }
Die Ausgabe dieses Programmes ist:
setX: min=0, max=5, start=1 setY: min=0, max=20, start=5
Wie man an dem Beispiel sieht, können Annotationen wie normale Objekte behandelt werden.
Vordefinierte Annotationen
Es gibt bereits einige vordefinierte Annotationen, dieser Abschnitt präsentiert eine Auswahl aus verschiedenen Packages.
java.lang
Name | Zweck |
---|---|
@Deprecated | Markiert Elemente (Klassen, Methoden, ...), die veraltet sind, oder aus anderen Gründen nicht benutzt werden sollten. Siehe auch Deprecated. |
@SuppressWarnings | Veranlasst den Compiler einen oder mehrere Typen Warnungen nicht zu melden. |
@Override | Markiert eine Methode, die eine andere Methode überschreibt. Ein Compiler kann dank dieser Annotation sicher sein, dass der Programmierer eine Methode absichtlich überschrieben hat. |
java.lang.annotation
Name | Zweck |
---|---|
@Retention | Regelt die Sichtbarkeit einer Annotation. Dazu wird eine RetentionPolicy gesetzt.
|
@Target | Wird ebenfalls für Annotationen angewandt. Das @Target sagt dem Compiler, welche Elemente eine Annotation markieren darf. @Target erwartet ein Array von ElementType.
Beispiel: Eine Annotation die für Methoden und Typen verwendet werden kann: 1 @Target( {ElementType.TYPE, ElementType.METHOD} )
2 public @interface Something{
3 ...
4 }
|
@Documented | Wird für Annotationen verwendet, die von Javadoc, und ähnlichen Programmen, dokumentiert werden sollen. Das ist insbesondere wünschenswert für Annotationen, deren Vorhandensein einen direkten Einfluss auf das Programm haben. |
@Inherited | Markiert eine Annotation, welche vererbt werden soll. Damit ist gemeint: wenn die Annotation eine Klasse markiert, sind automatisch alle Unterklassen ebenfalls markiert. |