In JDK gibt es eine Reihe verwandter Kompilierungs -APIs, die den Kompilierungsprozess in Java initiieren, Java -Quelldateien analysieren und seinen Syntaxbaum erhalten. Diese vollständige APIs ist in den Tools.jar von JDK enthalten (kann in/bibliothek/java/javavirtualmachines/jdk_version/contents/home/lib unter OSX gefunden werden). Dies ist jedoch keine öffentliche API in Oracle und OpenJDK -Veröffentlichungen, so dass diese offizielle Dokumentation diese APIS -APIS -Veröffentlichungen gibt. Viele Projekte haben diese API jedoch verwendet, um viele Dinge zu tun. Zum Beispiel verwendete der berühmte Lombok diese API, um den Syntaxbaum im Quellcode während der Annotationsverarbeitungsphase zu ändern. Das Endergebnis entspricht dem Einfügen neuer Code direkt in die Quelldatei!
Da dieser APIs derzeit nicht relevante Dokumente fehlen, ist es schwierig zu verwenden. Analysieren Sie beispielsweise alle Variablen im Quellcode und drucken Sie sie aus:
öffentliche Klasse Javaparser {private statische endgültige String path = "user.java"; Privat JavacFilemanager Filemanager; Privat Javactool Javactool; public Javaparser () {context context = new context (); fileManager = new Javacfilemanager (Kontext, true, charset.defaultCharset ()); javactool = new javactool (); } public void parsejavafiles () {iterable <!-? erweitert javafileObject-> files = fileManager.getjavafileObjects (Pfad); Javacompiler.comPilationTask CompilationTask = javactool.gettask (Null, Filemanager, Null, Null, Null, Dateien); Javactask Javactask = (Javactask) CompilationTask; versuche {iterable <!-? erweitert CompilationUnittree-> result = javactask.Parse (); für (compilationUnitree tree: result) {tree.accept (neuer sellvisor (), null); }} catch (ioException e) {e.printstacktrace (); }} statischer Klassenkürzung erweitert TreesCanner <void, void = ""> {private String currentPackagename = null; @Override public void VisitCompilationUnit (CompilationUnittree -Knoten, void vermeiden) {return Super.VISITEM -COMPILATIONUNIT (Knoten, vermeiden); } @Override public void VisitVariable (Variable -Knoten, void vermeiden) {formatptrln ("Variablenname: %s, Typ: %s, Art: %s, paket: %s", node.getName (), node.gettype (), node.getKind (), currentPackAnname); null zurückkehren; }} public static void formatptrln (String -Format, Objekt ... args) {System.out.println (string.format (format, args)); } public static void main (String [] args) {new Javaparser (). Parsejavafiles (); }} </void,>Der Code von user.java lautet wie folgt:
Paket com.gragnarok.javaparser; import com.sun.istack.internal.nullable; import Java.lang.Override; public class user {@nullable private string foo = "123123"; Privat Foo A; public void UserMethod () {} statische Klasse foo {private String fooString = "123123"; public void foomethod () {}}}Das Ergebnis der Ausführung des oben genannten Javaparser ist wie folgt:
Variable: Foo, Annotaion: NullableVariable Name: Foo, Typ: String, Art: Variable, Paket: com.gragnarok.javaparserver Variable Name: A, Typ: Foo, Art: Variable, Paket: com.ragnarok.javaparser
Hier analysieren wir zuerst die Quelldatei über Javacompiler.comPilationTask und verwenden dann den benutzerdefinierten Sourtsvisitor (von Treescanner geerbt), um auf die Struktur des Quellcode zuzugreifen. In der Quell -Visor -Klasse überlasten wir besuchsvariable, um eine Kompilierungseinheit (einzelne Quellcode -Datei) zu analysieren und auf alle Variablen zuzugreifen. Hier ist zu sehen, dass wir den vollständig qualifizierten Namen dieses variablen Typs (einschließlich Paketname) nicht erhalten und nur den entsprechenden einfachen Namen erhalten können. Die Bestimmung des Typs erfordert daher eine externe Implementierung, um sie selbst zu bestimmen. Sie können beispielsweise den Paketnamen aufzeichnen, in dem sich die Klasse befindet, rekursiv das gesamte Quellcode -Verzeichnis durchsuchen, um den vollständig qualifizierten Namen aller Klassen zu verfolgen und festzustellen, ob der Import den entsprechenden Typ usw. enthält.
Zusätzlich zur Besuchsvariable -Methode enthält TreesCanner eine große Anzahl anderer Visitxyz -Methoden. Beispielsweise können Sie alle Importe, Methodendefinitionen, Annotation usw. durchführen. Für genauer gesagt können Sie den Quellcode dazu in OpenJDK anzeigen.
Hier nehmen wir ein weiteres Beispiel: Überladen der VisitClass -Methode, um auf alle inneren Klassen und die Klasse selbst zuzugreifen:
@Overridepublic void VisitClass (ClassTree -Knoten, void vermeiden) {formatptrln ("Klassenname: %s", node.getSimpename ()); für (Baumelement: node.getMembers ()) {if (membersinstanceof variabletree) {variabletree variable = (variAlletree) Mitglied; Liste <!-? erweitert AnnotationTree-> Annotationen = variable.getModifiers (). getAnnotations (); if (Annotations.size ()> 0) {formatptrln ("Variable: %s, Annotaion: %s", variable.getName (), Annotations.get (0) .getAnnotationType ()); } else {formatptrln ("Variable: %s", variable.getName ()); }}} return Super.visitClass (Knoten, vermeiden); }Hier drucken wir einfach den Klassennamen und den variablen Namen, Typ und Annotationstyp. Führen Sie den obigen Code aus, und das Ergebnis lautet wie folgt:
Klassenname: UserVariable: Foo, Annotaion: NullableVariable: Klassenname: Foovariable: FooString
Es ist zu sehen, dass wir den Klassennamen und die Variablen in der Klasse ausgedruckt haben. In der VisualClass -Methode können wir alle Mitglieder der Klasse durch die GetMembers -Methode, einschließlich Variablen, Methoden, Annotation usw., erhalten, die verschiedenen Typen entsprechen. Beispielsweise entsprechen Variablen dem Typ Variable, und die Methode entspricht dem MethodTree -Typ.
Obwohl die Verwendung in der Tat nicht besonders kompliziert ist, hat sie aufgrund der mangelnden Dokumentation große Hindernisse für die Verwendung geführt. Und was wir vorstellen, ist nur ein kleiner Teil dieser API. Ich werde in Zukunft weiterhin die damit verbundenen Funktionen dieser API untersuchen.
Das obige ist eine Zusammenstellung von JDKs Parser -Daten, um den Java -Quellcode zu analysieren. Wir werden in Zukunft weiterhin relevante Informationen hinzufügen. Vielen Dank für Ihre Unterstützung für diese Seite!