home  |  suche  |  kontakt/johner  |  institut 
studierende  |  tech-docs  |  mindmailer 

Reflection und Annotation

Das Reflection-Modell erlaubt es uns, Klassen und Objekte, die zur Laufzeit von der JVM im Speicher gehalten werden, zu untersuchen und in begrenztem Umfang zu modifizieren. Reflection gehören in die Kategorie Meta-Programming, da sie auf den Klassen und Objekten anderer Programme operieren, es werden sogenannte Metadaten verwendet. Ein Metadatum ist eine Information über eine Information. In Java beschreibt ein Class-Objekt, was Klassen »können«, also welche Konstruktoren und Methoden sie haben, welche Attribute sie besitzen und wie die Erweiterungsbeziehungen sind. Um an die entsprechenden Daten zu gelangen, stehen folgende Methoden auf den Klassen java.lang.reflect.Method und java.lang.Class zur Verfügung. Weil man dabei in die Klasse "hereinschaut" und prüft was darauf definiert ist, spricht man dabei von Introspection.

Methoden auf "Method":

  • getName():String
  • getParameterTypes():Class[]
  • getReturnType():Class

Methoden auf "Class":

  • getConstructors():Constructor[]
  • getMethods():Method[] //öffentliche und vererbte Methoden
  • getDeclaredMethods():Method[] //private und öffentliche Methoden der Klasse, keine vererbten Methoden
  • isAbstract():boolean

"Declared" in der Methode getDeclaredMethods() bedeutet welche Methoden sind tatsächlich in der Klasse programmiert, also stehen in der Java-Klasse, egal ob private oder public. Methoden aus der Oberklasse werden hier nicht zurückgeliefert, weil diese sind nicht in der abgefragten Klasse beschrieben.

Hier ein Beispiel wie eine Klasse nur mit dem Klassenname als String instanziert und eine Methode mit Hilfe des Namens aufgerufen wird über Reflections.

Vor- und Nachteile Reflections

Vorteile Nachteile
Flexibilität - erst zur Laufzeit wird entschieden, welche Klasse/Methode instaziert/aufgerufen wird Performance
compilierter Code kann inspiziert werden (eventl. auch Nachteil) fehleranfällig (keine Kompiliersicherheit, Fehler erst zur Laufzeit)
kann in verteilten Anwendungen zum Einsatz kommen

Auch bei Annotations geht es um Metadaten. Mit Annotations ist es dem Programmiere möglich Metadaten Klassen, Methoden, Attributen usw. hinzuzufügen. Annotations haben verschiedene Nutzen, z.B.

  • Informationen für den Compiler (Fehlerentdeckung, Warnings ausblenden...)
  • Verarbeitung während der Entwicklungs- und Kompilierzeit, z.B. nutzen Softwaretools Annotations um Code, XML Dateien usw. zu generieren
  • Informationen währen der Laufzeit mit Annotations

Bekannte Annotations sind z.B. @Deprecated (nicht mehr benutzen, abgelehnt) oder @Override (eine Methode der Oberklasse wird überschrieben), diese Annotations werden vor eine Methode gestellt.

Annotations stehen erst mit Java 5.0 zur Verfügung.

Um etwas als Annotations zu deklarieren, wird immer das @-Zeichen vorangestellt.

Folgendes Beispiel zeigt wie man Informationen (Metadaten) in diesem Fall einer Klasse hinzufügt.

package annots;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PACKAGE})
public @interface VendorInformation {
  String firmename();
  int anzahlangestellte();
  enum Land{Deutschland, Schweiz};
  Land land();
  //String[] vornamen();
}
//Hier werden den oben definierten Informationen Werte zugewiesen, 
//diese gehören nun zu der Klasse Film  
package annots;

@VendorInformation(
    anzahlangestellte=12,
    land = VendorInformation.Land.Deutschland,
    firmename = "HTWG")
public class Film {
  private String titel;
  private int dauer;
  ...

Die einzelnen Informationsteile dürfen String, primitive, Annotations, Enums, Class und Arrays (aus den entsprechenden Typen) als Rückgabewerte haben.

Man hat die Möglichkeit bei der Definition der Anntotaionstruktur bestimmte Wertigkeitsbereiche mitanzugeben, was wiederrum mit Annotations passiert, man annotiert sozusagen Annotations.

  • @Retention - Sichtbarkeit (SOURCE, CLASS, RUNTIME)
  • @Target - was damit annotiert werden darf (TYPE, METHOD...)

Die Annotations und ihre Informationen kann man jederzeit über die Methode getAnnotations() auf der Klasse java.lang.Class auslesen.

package annots;

import java.lang.annotation.Annotation;

public class ReadAnnotation {
  public static void main(String[] args) {
    Class film = Film.class;
    Annotation[] annotationen = film.getAnnotations();
    System.out.println("Wir haben " + annotationen.length + " Annotationen");
    for (Annotation annotation: annotationen){
      System.out.println("Wir haben die Annotation " + annotation);
    }
  }
}