icancode.de

Eigene Java Annotations – Teil 0

Einleitung

Torsten T. Will

Torsten T. Will

Informatik, Biologie, Programmierung, Fotografie, C++, Python, Java.


Neuste Artikel

Datum in Java 11th November, 2015

Eigene Java Annotations – Teil 1 03rd November, 2015

Java

Eigene Java Annotations – Teil 0

Veröffentlicht am .

Man kann in seinem Java-Code auch eigene Annotations verwenden. Aber wann ist das eigentlich sinnvoll?

Ich setzte das hauptsächlich zu zwei verschiedenen Zwecken ein:

  • Boilerplatecode reduzieren — also unnötige Wiederholungen vermeiden
  • Programmierunterstützung durch zusätzliche Überprüfungen und „Sanity Checks“

Ersteres heißt, dass ich zur Laufzeit des Programms mir ein Java-Sprachelement auf eine Annotation hin untersuche und dann eventuell speziellen Code ausführe. Dafür gibt es Annotationen mit der Retension.RUNTIME — das heißt, die Annotation wird mit in die Classfiles gepackt und steht auch während der Ausführung des Programms zur Verfügung. Es liegt in der Natur der Dinge, dass man nichts „magisches“ tun kann, was man ohne Annotationen nicht auch hinbekommen würde — der Code wandert meist einfach woanders hin: Wenn ich eine Methode annotiere zum Beispiel weg von der Methode zum Orte ihrer Verwendung. Man könnte diese Verwendung als eine Anwendung des Interceptor-Design-Patterns sehen (nur grob). Im [Teil 1] schauen wir uns ein Beispiel dazu an.

Spannender wird es, wenn man einen Annotation Processor schreibt: Ein solcher klinkt sich in die Compiler, also javac, ein. Wenn dieser auf eine Annotation stößt, kann man die lustigsten Dinge tun: Von eine (Fehler-)Meldung ausgeben, bis zur automatischen Codegenerierung. Die Annotation wird nur während der Übersetzungsphase gebraucht, wird also nicht als Ballast in die Classfiles übernommen und hat somit eine Retension.COMPILE. In [Teil 2] schauen wir uns an, wie wir eigene Compilermeldungen erzeugen können. Zumindest Netbeans kann diese selbst erzeugten Fehler dann sogar in der IDE anzeigen.

Nur damit ihr eich vorstellen könnt, worum es eigentlich geht. Ich habe eine eigene einfache Workflowengine, die per Reflection selbst entscheidet, welche Methoden eine Klasse sie ausführt. Eine solche Methode sieht zum Beispiel so aus:


  @StepInfos(stepid=10, description="Initialisiere Daten")
  @ExceptionHandling(next=NextType.IGNORE, logging=LoggingType.NONE, onException=NumberFormatException.class)
  @ExceptionHandling(next=NextType.RETRY, logging=LoggingType.BRIEF, onException=MyCommException.class)
  @ExceptionHandling(next=NextType.STOP, logging=LoggingType.FULL) // anything else
  public void step_10() {
    ....
  }

Die @StepInfos können erstens zur Laufzeit in der GUI Informatinen über den Prozess ausgeben, werden zweitens aber auch dazu verwendet, zur Compilezeit zu überprüfen, ob Sichtbarkeit, Rückgabetypen und Parameter der step_...-Methode passen. Mehr dazu in [Teil 1].

Die Annotation @ExceptionHandling spart mir einen immer wiederkehrenden try-catch-Block in den Step-Methoden. Der hochkonfiguruerbare Aufrufer sorgt an einer zentralen Stelle dafür, dass alle möglichen Fehlerszenarien richtig behandelt werden. Das sehen wir uns in [Teil 2] an.

Torsten T. Will

Torsten T. Will

http://cpp11.generisch.de/

Informatik, Biologie, Programmierung, Fotografie, C++, Python, Java.

Navigation