Annotation (Java): Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
K (java.lang.annotation)
K (Annotation definieren)
 
(3 dazwischenliegende Versionen von 2 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 gennanten sein.
+
* 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:
<code=java>
+
<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;
 
}
 
}
</code=java>
+
</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:
<code=java>public class Point {
+
<syntaxhighlight lang="java">public class Point {
 
     private int x, y;
 
     private int x, y;
 
      
 
      
Zeile 47: Zeile 47:
 
         list( Point.class );
 
         list( Point.class );
 
     }
 
     }
}</code=java>
+
}
 +
</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:
<code=java>   public static void main( String[] args ) throws Exception{
+
<syntaxhighlight lang="java" line='line'>
 +
    public static void main( String[] args ) throws Exception{
 
         list( Point.class );
 
         list( Point.class );
 
     }
 
     }
Zeile 69: Zeile 71:
 
             }
 
             }
 
         }
 
         }
     }</code=java>
+
     }
 +
</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 111: 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:
<code=java>@Target( {ElementType.TYPE, ElementType.METHOD} )
+
<syntaxhighlight lang="java" line='line'>
 +
@Target( {ElementType.TYPE, ElementType.METHOD} )
 
public @interface Something{
 
public @interface Something{
 
  ...
 
  ...
}</code=java>
+
}
 +
</syntaxhighlight>
  
 
  |-
 
  |-
Zeile 125: Zeile 130:
 
|}
 
|}
  
[[Kategorie:Programmierung]]
 
[[Kategorie:Programmierung Grundlagen]]
 
 
[[Kategorie:Java]]
 
[[Kategorie:Java]]
 
[[Kategorie:Java Grundlagen]]
 
[[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.

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:

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.
  • Source: Die Annotation ist nur im Quellcode sichtbar.
  • Class: Die Annotation ist auch in der Class-Datei, also im Kompilat, vorhanden.
  • Runtime: Die Annotation wird während der Laufzeit von der JVM geladen. Nur mit dieser Policy kann eine Annotation per Reflection ausgelesen werden.
@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.