In c\c++
kann definieren:
meine Frage, gibt es eine Möglichkeit, es in Java zu tun? (die keine globale statische Variable definiert ..) zum Beispiel möchte ich etwas Code nur im Debug-Modus ausführen.
Danke!
Die Antwort ist Nein. Nicht in dem Sinne, den Sie meinen.
Die Art, wie Sie diese Art von Dingen in Java machen, ist wie folgt:
%Vor% Java hat keinen Präprozessor (wie C und C ++). Der Compiler optimiert jedoch den unbenutzten Zweig einer if
-Anweisung wie oben, PROVIDIERT, dass flag
ein kompilierbarer konstanter Ausdruck ist. Dies ist eine eingeschränkte Form der bedingten Kompilierung. Beachten Sie, dass die Konstante flag
aus einer anderen Klasse importiert werden kann.
(IIRC, dieses Verhalten ist in der JLS ... angegeben, was bedeutet, dass Sie sich darauf verlassen können, dass ein entsprechender Java-Compiler das tut.)
@Treebranch merkt an, dass "dies" Code aufblähen kann.
Wenn @Treebranch über den Objektcode bloat spricht, ist das nicht wahr. Wenn Sie dies richtig mit Flags / Ausdrücken tun, die kompilierungszeitkonstante Ausdrücke sind, wie von der JLS definiert, dann gibt der Compiler keine Bytecodes für den "bedingt ausgeschlossenen" Quellcode aus. Siehe @ edalorsos Antwort.
Wenn @Treebranch über Source-Code Bloat spricht, stimme ich zu. Aber Sie können dasselbe für die bedingte Kompilierung von #ifdef
sagen. (Makros und #include
können verwendet werden, um Quellcode-Bloat zu reduzieren ... aber nur auf Kosten von Lesbarkeit, Wartbarkeit, etc. Und das war der Grund, warum die Java-Entwickler es ablehnten, irgendeine Quellcode-Vorverarbeitung zu unterstützen.)
Java bietet eine bessere Möglichkeit, mit Plattformunterschieden, Funktionsvariationen usw. umzugehen: Verwenden Sie dynamische Bindung . Wenn Sie viele verschiedene Plugin-Klassen in Ihrem JAR haben (Bytecode Bloat), können Sie damit umgehen, indem Sie für jede Plattform eine andere JAR-Datei erstellen, oder was auch immer.
Der Ansatz, der darauf hinweist, dass die Verwendung der endgültigen statischen booleschen Variablen dem vorgeschlagenen Feature am nächsten kommt, da sie sogar vom Compiler optimiert wird. Wenn das Flag auf "false" gesetzt ist, werden die im Block enthaltenen Bytecodes nicht einmal erzeugt.
Lassen Sie mich ein Beispiel zeigen:
%Vor%Dies erzeugt die Bytecodes
%Vor%Aber wenn wir die Flagge ausschalten ...
%Vor%Die Bytecodes sehen wie folgt aus
%Vor%Also, AFAIK, das ist das Beste, was Sie mit einer Precompile-Direktive in Java erreichen können.
Es gibt keine bedingte Kompilierung in Java. (wie Xea sagte)
Abhängig von dem Problem, das Sie lösen möchten, gibt es verschiedene Möglichkeiten, etwas Ähnliches zu tun.
Man verwendet eine statische letzte Variable, die auf eine Kompilierzeitkonstante gesetzt wird (wie Stephen schreibt). Der Compiler wird den Bytecode für den unmöglichen Pfad tatsächlich nicht enthalten. Aber es muss immer noch legales Java sein, was bedeutet, dass man eine Variable nicht in einem solchen Block deklarieren und in einem anderen verwenden kann.
Ich konnte alle Fälle, die ich bisher gesehen habe, mit Hilfe von OO-Konstrukten lösen. Zum Beispiel können Sie Ihren if else durch einen Aufruf einer abstrakten Methode ersetzen und eine Debug- und eine Produktionsimplementierung bereitstellen.
Java als Sprache hat keine ähnliche Vorverarbeitung oder Makros wie C oder C ++, jedoch gibt es einige Drittanbieter Präprozessor - Werkzeuge, die solche Dinge handhaben können. Für den praktischen Gebrauch müssten Sie sie in einen Maven- oder Ant-Build verbinden.
Ich denke, was @ StephenC vorgeschlagen hat, ist eine gute Option. Alternativ können Sie versuchen, mit AspectJ den gewünschten Code für eine bestimmte Implementierung einzuflechten. Sie können dann einfach den Aspekt entfernen (nicht in den Code einweben), wenn Sie es nicht als Teil der Implementierung wollen. AspectJ ändert den Bytecode (kompilierter Java-Code) basierend auf den von Ihnen angegebenen Positionstypen (so genannte Pointcuts). Dies ist besonders gut geeignet für Dinge wie Hinzufügen von Protokollierung zu Ihrem Programm.
Wenn Sie an diesem Verfahren interessiert sind, besuchen Sie AspectJ und Referenzhandbuch .
Der oben eingefügte Ausschnitt war ein Makro für die bedingte Kompilierung , das für den Präprozessor gedacht ist, der Ihren Quellcode "transformiert" vor der Zusammenstellung.
Java hat nicht das entsprechende Sprachkonstrukt, also können Sie das nicht tun.
Bearbeiten: Sie können jedoch normale Bedingungen verwenden, um Ihr Ziel zu erreichen, da der Compiler auf diese Weise den Bytecode auf die gewünschte Weise optimiert (Danke für @StephenC, um dies zu verdeutlichen).
Aber ich persönlich bevorzuge es, die API für das Debuggen wo nötig zu erweitern, was die Implementierungsdetails verbergen und die Laufzeit ändern kann. Dies ist natürlich szenariospezifisch.
Zum Beispiel wäre das ähnlich Log4j-s API , mit der Sie überprüfen können, ob sich Ihr Code im Debug-Modus befindet oder nicht.
Ich würde die Verwendung dieses Musters empfehlen, weil das (zu sehr) unsere geliebten objektorientierten Konzepte nicht unterbricht.
Tags und Links java