6

Ich habe eine benutzerdefinierte Annotation, die ich implementiert habe, und ich möchte einen Annotationsprozessor verwenden, um eine Liste aller Klassen in meiner App zu generieren, die sie verwenden diese bestimmte Anmerkung.Verwenden eines Annotation Processors zum Erstellen einer Liste von Klassen mit einer bestimmten Annotation

Ich habe this tutorial gefunden, die beschreibt, wie man eine Klassendatei mit einem Annotationsprozessor erzeugt, so dass es ziemlich einfach sein sollte, eine Klasse für jede Klasse mit meiner Annotation zu generieren.

Was ich nicht herausfinden kann ist, wie ich all diese Informationen in einer einzigen Klasse sammeln kann. Es scheint keine Möglichkeit zu geben, eine Klasse zu ändern, daher kann ich keine neuen Elemente an die Liste anhängen, wenn die Klasse das erste Mal generiert wurde.

Gibt es eine Möglichkeit, einen Annotationsprozessor zu verwenden, um eine Methode zu generieren, die die Liste aller Klassen in einer App zurückgibt, die mit einer bestimmten Annotation versehen sind?

Antwort

4

Generierte Klassen müssen nicht notwendigerweise eins zu eins mit den zu verarbeitenden Eingabeklassen übereinstimmen. Darüber hinaus können Sie für die Klassen (Elemente) suchen, die mit einem bestimmten Anmerkung über die RoundEnvironment kommentierte sind:

roundEnvironment.getElementsAnnotatedWith(MyAnnotation.class) 

Daraus Sie eine einzelne Klasse mit einem Verfahren erzeugen kann, die fand eine Sammlung der Klassen zurückgibt.

Ein paar Fragen rund um diese zu markieren:

  • Annotation Prozessoren können zusammen mit anderen Annotation Prozessoren laufen und somit mit Klassen erzeugt während der Kompilierung zu tun haben. Um dies zu unterstützen, wird die Java-Annotationsverarbeitung in Runden durchgeführt, damit Prozessoren die Ausgaben anderer abfangen können. Um mit anderen Prozessoren kompatibel zu sein, müssen Sie die ErrorType elegant handhaben.
  • Nur Klassen im aktuellen Kompilierungsdurchlauf werden von den Methoden RoundEnvironmnet zurückgegeben, sodass Klassen in externen Bibliotheken nicht enthalten sind.
  • IDEs (hust hust Eclipse) implementieren die Annotationsverarbeitungsfunktionen von Java anders, was ein Problem für Prozessoren sein kann, die eine vollständige nicht-partielle Kompilierung erfordern, wie ich es beschrieben habe.

Zufälligerweise habe ich ein ähnliches Projekt vor kurzem das tut, was Sie suchen:

https://github.com/johncarl81/silver

Silber ist sehr viel ein WIP und verwendet eine Menge von Bibliothekscode die Aufgabe zu erfüllen, aber es kann dir eine Idee geben, was möglich ist.

+1

Hey John! Schön von Ihnen zu hören :) Silver sieht ziemlich gut aus, was ist der Laufzeiteinfluss von SilverUtils.getAnnotated()? Außerdem, was, wenn überhaupt, muss es zur Laufzeit außerhalb der Klassen, die mit Anmerkungen versehen sind, in den Klassenlader hineingezogen werden? – emmby

+0

Gut von dir auch Mike zu hören! Das Coolste an diesem Ansatz ist, dass die Laufzeit so schnell wie möglich ist. Sobald Sie eine Instanz von Example haben, besteht die einzige Laufzeitkosten darin, eine statische Variable zurückzugeben. SiverUtil.get() führt eine kleine Reflektion von Lookup-Klassen durch (ein Aufruf von Class.forName()), aber dieser Aufruf wird zwischengespeichert und daher nur einmal ausgeführt. SilverUtil ist eigentlich nur für die Bequemlichkeit da, technisch müssen Sie es nicht verwenden, um den generierten Code zu verwenden. –