Annotation Target, AnnotationProcessor Debug

Kekute

Grünschnabel
Hallo,

gibt es eine Möglichkeit das Target einer Annotation auf bestimmte Klassen einzuschränken?
Ich möchte eine Annotation an eine Klassenvariable schreiben können unter der Voraussetzung das der Typ der Klassenvariable einer bestimmten Klasse entspricht.

Grüsse
Kekute
 
Hallo,

das geht so ohne weiteres nicht direkt. Du müsstest dir einen AnnotationProcessor definieren welcher deine Annotation mit Target (ElementType.Field) zusätzlich noch auf den passenden Typ des Feldes prüft.

Hier mal ein kleines Beispiel dazu:
Unsere CustomAnnotation soll nur auf Felder awendbar sein, welche vom Typ javax.swing.table.TableModel sind.

Java:
package de.tutorials.training;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CustomAnnotation {
}

Unsere Annotation Test-Klasse:
Java:
package de.tutorials.training;

import javax.swing.table.TableModel;

public class CustomAnnotationTest {
  @CustomAnnotation
  static Object /* TableModel */ bubu;
}

unser AnnotationProcessor:
Java:
package de.tutorials.training.apt;

import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.swing.table.TableModel;
import javax.tools.Diagnostic.Kind;

import de.tutorials.training.CustomAnnotation;

@SupportedAnnotationTypes(value = { "de.tutorials.training.CustomAnnotation" })
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class CustomAnnotationProcessor extends AbstractProcessor {

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

    Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(CustomAnnotation.class);
    for (Element annotatedElement : annotatedElements) {
      TypeMirror typeMirror = annotatedElement.asType();

      if (!TableModel.class.getName().equals(typeMirror.toString())) {
        processingEnv.getMessager().printMessage(Kind.ERROR, "CustomAnnotation is only allowed for fields of Type " + TableModel.class.getName(), annotatedElement);
      }
    }

    return true;
  }
}

Verwendung:

Da der Typ des mit der CustomAnnotation annotierten Feldes nicht TableModel ist wird beim
kompilieren mit unserem AnnotationProcessor eine Warnung ausgegeben:
Code:
C:\dev\workspaces\training\de.tutorials.training\src>javac -cp ../bin -processor de.tutorials.training.apt.CustomAnnotationProcessor de/tutorials/training/CustomAnnotationTest.java
de\tutorials\training\CustomAnnotationTest.java:7: CustomAnnotation is only allowed for fields of Type javax.swing.table.TableModel
  static Object /* TableModel*/ bubu;
                                ^
1 error

Nun ändern wir den Typ von Object zu TableModel .

Code:
C:\dev\workspaces\training\de.tutorials.training\src>javac -cp ../bin -processor de.tutorials.training.apt.CustomAnnotationProcessor de/tutorials/training/CustomAnnotationTest.java

Nun führt javac unseren AnnotationProcessor erneut aus und kompiliert die Datei diesmal ohne Warnungen.

Mit dem erweiterten Aufruf:
Code:
C:\dev\workspaces\training\de.tutorials.training\src>javac -J-agentlib:jdwp=transport=dt_socket,server=y,address=8001 -cp ../bin -processor de.tutorials.training.apt.CustomAnnotationProcessor de/tutorials/training/CustomAnnotationTest.java
Listening for transport dt_socket at address: 8001
kann man javac und das AnnotationProcessing wie unter http://www.tutorials.de/java/189239-java-anwendungen-remote-debuggen.html gezeigt auch Remote Debuggen.

Gruß Tom
 
Zurück