Wenn ich eine benutzerdefinierte Annotation erstelle (Beispiel: @SaveFuncName("saveMe")
fügt eine Methode namens saveMe()
mit Code hinzu, den mein Prozessor generiert), kann der Javac Compiler meinen Annotationsprozessor verwenden, um eine Methode zur Klasse hinzuzufügen? Oder kann ich nur eine andere Klasse erstellen?Kann ich einer Klasse eine Methode aus einer Kompilierungszeitanmerkung hinzufügen?
Antwort
Oder kann ich nur eine andere Klasse erstellen?
Das stimmt. Die vorhandene API lässt uns vorhandene Klassen nicht ändern, sondern nur neue generieren.
Technisch gesehen, wenn Sie etwas Hacky-Zeug machen wollen, ist es möglich, die interne Syntax-API zu verwenden, um den abstrakten Syntaxbaum direkt zu ändern, aber es ist nichts für schwache Nerven. Zum Beispiel ist ein Objekt wie TypeElement
tatsächlich ein Symbol direkt von Javac, von uns von der Schnittstelle verborgen. Der Syntaxbaum ist auch in einem schreibgeschützten Modus über die compiler tree API verfügbar. Wir können die Schnittstellen wegwerfen und den Code auf diese Weise modifizieren. Dies ist z.B. Project Lombok funktioniert.
(Aber ich kann nicht empfehlen zu tun. Ich bin es meist zu erklären, weil Lombok eine Sache, die es gibt, ist so wie Klassen zu modifizieren aussieht, ist möglich.)
Die einfachste Lösungen sind etwas zu tun erzeugen eine Oberklasse mit zB saveMe()
Methoden und erweitern Sie es oder generieren Sie eine Dienstprogrammklasse und delegieren Sie sie. (Auch empfohlen here.)
Da Oracle Lombok in seinem "Java Magazine" vom Mai 2017 vorstellt ... bedeutet das, dass sie sich für Hacky-Kram aussprechen oder APT erlauben könnten, die aktuelle Datei zu ändern? Diese Frage brachte mich hierher, als ich den Artikel las, denn Lombok schien genau das zu tun. Aber ich denke, es gibt keine elegante Möglichkeit, das in die APT-API zu integrieren, und Sie müssten den AST trotzdem bearbeiten. – Stroboskop
@Stroboskop Es ist hacky, weil es undokumentiert ist, also musst du den javac-Quellcode lesen, um herauszufinden, wie es funktioniert. Es könnte sein, dass der Autor dieses Artikels nicht weiß, was Lombok hinter den Kulissen tut. Lombok hat seinen eigenen Klappentext, wenn Sie sehen wollen, was sie sagen: http://jnb.ociweb.com/jnb/jnbJan2010.html#controversy Persönlich hoffe ich, den AST zu modifizieren, oder zumindest nur Methoden hinzuzufügen, wird als hinzugefügt ein Feature, aber ich bezweifle, dass es in nächster Zeit passieren wird. – Radiodef
- 1. Mit einer Methode aus einer anderen Klasse
- 2. Kann eine Methode aus einer anderen Klasse nicht aufrufen
- 3. Wie eine übergeordnete Klasse Methode aus einer geschachtelten Klasse zuzugreifen?
- 4. Kann ich multiprocessing.Pool in einer Methode einer Klasse verwenden?
- 5. Hinzufügen einer neuen Methode zur Array-Klasse
- 6. Wie kann ich eine private Methode einer Delphi-Klasse patchen?
- 7. Hinzufügen einer Methode zu einer Domänenklasse
- 8. Verwenden einer Methode aus einer anderen Klasse im Hauptformular
- 9. Aufruf Methode aus einer anderen Klasse
- 10. Wie führe ich eine Methode/Funktion für eine Instanz aus einer nicht instanziierten Klasse aus?
- 11. eine Aktivität Methode aus einer BroadcastReceiver Klasse Rufen
- 12. Hinzufügen einer Klasse zu einer ArrayList-Sammlung
- 13. Android Rufen Sie eine Methode aus einer anderen Klasse
- 14. Starten einer Klasse aus einer separaten Klasse
- 15. Aufruf einer Methode aus einer anderen Klasse ruby
- 16. RUBY - So rufen Sie eine Methode aus einer anderen Klasse
- 17. Template Spezialisierung einer einzigen Methode aus einer Templat-Klasse
- 18. Aufruf einer Set-Wert-Methode aus einer anderen Klasse
- 19. Wie würde ich eine Methode aus einer Klasse mit einer Variablen aufrufen?
- 20. Python - wie kann ich eine Methode dynamisch aus einer Klasse entfernen - dh Gegenteil von setattr
- 21. In Java, wie können wir eine Instanz einer Klasse aus einer Methode innerhalb der Klasse
- 22. Hinzufügen einer Methode zu einer untergeordneten Klasse mit dem Namen einer geerbten Methode
- 23. Wie kann ich Methoden aus einer Klasse in Ruby aufrufen?
- 24. Wie kann ich eine Aktivität aus einer Nicht-Aktivitätsklasse starten?
- 25. Kann eine void-Methode in einer Klasse in Java
- 26. Aufruf einer Methode von einer Klasse in eine andere
- 27. Aufruf einer Methode einer Klasse, die Thread aus einer anderen Klasse
- 28. Warum kann ich die statische Methode einer inneren Klasse nicht statisch auf eine generische Klasse verweisen?
- 29. Eine Methode nur aus einer Instanz entfernen
- 30. Wie dekoriere ich eine Methode in einer Klasse?
Nein, das ist nicht möglich. Wenn Sie die interne Javac-API lernen, ist es möglich, den Syntaxbaum direkt zu ändern, aber es ist nichts für schwache Nerven. Etwas verwandt: http://stackoverflow.com/questions/13690272/code-replacement-with-annannotation-processor. Am einfachsten ist es, eine Superklasse mit z.B. 'saveMe()' und erweitere es. – Radiodef
@Radiodef Danke. Kannst du das als Antwort posten und ich werde es als beantwortet markieren. –