Gibt es eine Möglichkeit, dem Java-Compiler eine Art Variable zu geben, auf die der laufende Java-Code zugreifen kann?
In C / C ++ kann ich die Kompilierung -DKEY=VALUE
geben und das würde dazu führen, dass der Präprozessor eine #define
für KEY gleich VALUE hat. Ich kann dann diesen Wert in der Kompilierzeit überprüfen, um zu bewirken, welcher Code kompiliert wird.
Ich habe java
's -D gefunden, aber die Werte geben die java
Befehlszeile in System.getProperty()
. Ich möchte ein Argument geben in der Kompilierzeit, nicht Aufrufzeit.
Mit Java-Anmerkungen ist es möglich, zusätzlichen Code im laufenden Betrieb zu erzeugen, der in der Befehlszeile konfiguriert werden kann. Es erlaubt, mehr Quellcode, Konfigurationsdateien, XML-Dateien, ... zu produzieren. Die Haupteinschränkung ist, dass Sie nur neue Quelldateien (neu) erzeugen dürfen, die Sie nicht ändern können.
Nachstehend finden Sie ein kurzes Tutorial, wie Sie vom javac-Befehl Parameter angeben können, die im Java-Code sichtbar sind. Wie nützlich ist das? Ie. Sie könnten eine boolesche Option angeben, die einige Teile des Codes deaktiviert. Ich bin sicher, dass diese Teile des Codes mit Tools wie proguard entfernt oder sogar von javac optimiert werden können. Eine andere Verwendung besteht darin, eine neue Versionsnummer anzugeben. Diese Anwendungsfälle sind meistens, wofür C ++ - Makros verwendet werden.
Du brauchst also:
Sie müssen auch Ihre Prozessor-Datei kompilieren, bevor Sie die Main-Klasse kompilieren. Dies geschieht natürlich nur, wenn die Prozessorklasse geändert wird. Alle drei Dateien sind am unteren Rand. Jetzt sieht die Zusammenstellung wie folgt aus (Ich bin auf Windows):
Kompilierprozessor:
%Vor%Dann Main.java mit zusätzlichen Parametern zum Prozessor:
%Vor%Und das ist alles, jetzt können Sie Main.class ausführen und es wird die Optionsklasse verwenden, die während der Kompilierung mit den oben genannten Parametern erzeugt wird. Es sieht so aus:
%Vor%ProcessorStarterAnnotation.java
%Vor%Main.java
%Vor%ConfigWriterAnnotationProcessor.java
%Vor% javac
hat das
Befehlszeilenoption zum Übergeben von Informationen an Annotationsprozessoren .
In Java gibt es nichts Vergleichbares. Kompilierzeitkonstanten müssen im Quellcode deklariert werden, und soweit ich weiß, gibt es keinen Vorprozessor.
Übrigens könnten Sie Flags verwenden, die an java
Kommandozeile (-Dargs) übergeben werden, um Java-Konstanten zur Laufzeit zu initialisieren, die das nachahmen, wonach Sie suchen.
Beispiel:
%Vor% Rufen Sie mit java Xxx -Dfoo.bar=foobar
Da es in Java keine Vorverarbeitung gibt, sollten Sie Ihre eigenen entwerfen.
Man könnte daran denken, einen Standard-C-Präprozessor oder einen benutzerdefinierten zu verwenden und die vorverarbeitete Ausgabe zu kompilieren, aber dies hat den Nachteil, dass die Dateien dupliziert werden, so dass das Projekt komplexer wird und die Unterstützung von der Entwicklungsumgebung wird degradieren (wie die Fähigkeit, zu einem Syntaxfehler zu springen).
Mein Vorschlag besteht darin, Kommentare über Kommentare zu verwenden, die einen benutzerdefinierten Präprozessor leiten und vor dem Kompilieren Ersetzungen ermöglichen.
Zum Beispiel
%Vor%würde
werden %Vor%Dann würde Ihr Präprozessor eine Definitionsdatei wie
haben %Vor%Drehen Sie den Code in
%Vor%Ähnlich können Sie die Kompilierung von bedingten Codes mit
emulieren %Vor% welches vom Präprozessor (mit einer Definition wie PRINT OFF
) in
Sie können alternative Syntaxen verwenden, aber die Hauptideen sind
Es wäre gegen das Design der Sprache, es so zu haben. Was -DKEY=VALUE
tut, ist, dass es tatsächlich KEY
durch VALUE
in der Quelle während des Präprozessors in C / C ++ ersetzt.
Java hat keinen Präprozessor, daher ist dieser Mechanismus nicht verfügbar. Wenn Sie etwas "Äquivalent" wollen, müssen Sie sich fragen, was Sie damit meinen. Wenn die Quelle nicht vorverarbeitet wird, wäre das nicht wirklich äquivalent.
Wenn Sie andererseits möchten, dass der Wert des Symbols KEY
auf den Wert VALUE
gesetzt wird, würden Sie auf das Problem stoßen, dass Sie das Symbol% co_de% auf jeden Fall trotzdem deklarieren müssten bestimmen Sie den Typ. In diesem Fall wäre es nur eine weitere Konstante / Variable mit den zugehörigen Constraints.
Das bedeutet, dass selbst mit einer solchen Funktion der generierte Code nicht geändert würde und Sie kaum besser wären, als den Wert für die Startzeit festzulegen. Deshalb wäre die Angabe des Parameters über KEY
der richtige Weg.