javac entspricht "-D"?

7

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.

    
shoosh 14.01.2016, 11:09
quelle

5 Antworten

7

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:

  • eine Dummy-Annotationsklasse, die es dem Prozessor ermöglicht, ausgeführt zu werden. Es sollte nur einmal in Ihrer Anwendung angegeben werden.
  • eine Prozessorklasse, die für die obige Dummy-Annotation ausgeführt wird und eine Optionsklasse generiert. Es liest auch Optionen von der javac-Befehlszeile.
  • eine Dummy-Hauptklasse für Testzwecke.

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%     
marcinj 29.01.2016, 12:06
quelle
10

javac hat das

%Vor%

Befehlszeilenoption zum Übergeben von Informationen an Annotationsprozessoren .

    
wero 14.01.2016 11:14
quelle
2

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

auf     
spi 14.01.2016 11:19
quelle
1

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

umgewandelt werden könnte %Vor%

Sie können alternative Syntaxen verwenden, aber die Hauptideen sind

  • dass der mit Anmerkungen versehene Code kompilierbar bleibt,
  • dass die Präprozessor-Substitutionen reversibel sind.
Yves Daoust 26.01.2016 11:00
quelle
0

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.

    
skyking 14.01.2016 11:50
quelle

Tags und Links