nicht direkt. Höchstens über eine Statische Klasse mit diversen Options kannst du solche Präprozessor Direktiven "Simulieren" Sinnvoll ists allemal sowas zu machen. Ich habe immer entweder eine rein Statische Klasse (Also nur Statische Funktionen) oder eine Singleton klasse mit solchen Optionen drinnen die ich dann abfragen kann
sowas wie.
Code:
if (Options.getDebug() ) System.out.println(....);
direkte Präprozessordirektiven gehen nicht sind aber auch nicht wirklich von nöten.
Nicht wirklich.
Du könntest z.B. eine Systemvariable setzen und abfragen. Oder du benutzt ein Logging-Framework (log4j, java.util.logging), dort kannst du das Log-Level setzen. Selbiges läßt sich sicher auch auslesen, um davon abhängig Code zu starten, aber das halte ich für schlechten Stil / aufkommenden Wahnsinn. Dann gibt es noch assert, das man über Kommandozeilenparamter ein- und ausschalten kann.
for (int i=0; i<10000000; i++)
{
// In der innersten Schleife, wird gaaaanz oft ausgeführt:
log(level, "Das Objekt ist "+einKomplexesObjektDessenToStringMethodeZehnMinutenRechnet);
}
Selbst wenn das logLevel besagt, dass garnichts ausgegeben wird, wird trotzdem der String gebaut.... :?
Abhilfe sind da ggf. solche sachen wie
Code:
private static final boolean LOCAL_BEDUG = false;
...
if (LOCAL_DEBUG) log(level, "Das Objekt ist "+einKomplexesObjektDessenToStringMethodeZehnMinutenRechnet);
allerdings werden damit die LogLevel auch ad absurdum geführt....
Selbst wenn das logLevel besagt, dass garnichts ausgegeben wird, wird trotzdem der String gebaut.... :?
Abhilfe sind da ggf. solche sachen wie
Code:
private static final boolean LOCAL_BEDUG = false;
...
if (LOCAL_DEBUG) log(level, "Das Objekt ist "+einKomplexesObjektDessenToStringMethodeZehnMinutenRechnet);
allerdings werden damit die LogLevel auch ad absurdum geführt....
Um die Log-Level zu berücksichtigen, kann man dann besser mit org.apache.log4j.Logger.isEnabledFor bzw. java.util.logging.Logger.isLoggable arbeiten:
Code:
if (log.isEnabledFor( level)) log(level, "Das Objekt ist "+einKomplexesObjektDessenToStringMethodeZehnMinutenRechnet);
Die Variante mit der static final Konstante hat allerdings theoretisch den Vorteil, dass ein optimierender Compiler die gesamte Anweisung aus dem Code entfernen kann.
Die Variante mit der static final Konstante hat allerdings theoretisch den Vorteil, dass ein optimierender Compiler die gesamte Anweisung aus dem Code entfernen kann.
Die Variante mit der static final Konstante hat allerdings theoretisch den Vorteil, dass ein optimierender Compiler die gesamte Anweisung aus dem Code entfernen kann.
Im Regelfall sollte man darauf verzichten, und lieber die entsprechenden Methoden des Log-Frameworks (oder notfalls Systemvariablen) benutzen. In ein paar Ausnahmefällen ist die static-final-Konstante allerdings tatsächlich nützlich. Ich habe in einem Projekt ein Auto-Login ohne Passwortabfrage, welches nur bei Test-Kompilaten funktioniert. Dieser Teil des Codes sollte in der ausgelieferten Software nicht enthalten sein.
Mit dem Sun-Compiler und mit Jad hab ich getestet; die if-Anweisungen (inkl. Block, versteht sich) aller nachfolgenden Beispiele sind nach dem Kompilieren weg.
Code:
if (false) {
throw new InternalError();
}
Code:
public static boolean DEBUG = false;
void foo() {
if (DEBUG) {
throw new InternalError();
}
}
Code:
public interface Debug {
static boolean DEBUG = false;
}
public class Test {
void foo() {
if (Debug.DEBUG) {
throw new InternalError();
}
}
}
Da gebe ich Dir Recht; die "static final"-Konstante würde auch auch nur dort benutzen, wo der Code - wie in Deinem Fall - aus Sicherheitsgründen nicht in der ausgelieferten Version enthalten sein soll oder sich beim Profilen zweifelsfrei erwiesen hat, dass die Abfrage über das Log-Framework wirklich signifikante Performance-Nachteile bringt.
Allgemein wäre ich aber ohnehin sehr vorsichtig mit Konstrukten wie
Code:
if ( testModus()) {
/* mache etwas */
}
oder gar
Code:
if ( testModus()) {
/* mache etwas */
} else {
/* mache etwas anderes */
}
denn damit verhält sich das Programm im Testbetrieb ja anders als in Produktion
Die Variante mit der static final Konstante hat allerdings theoretisch den Vorteil, dass ein optimierender Compiler die gesamte Anweisung aus dem Code entfernen kann.
Ich gehe davon aus, dass sowohl mir als auch den Vorrednern Preprocessor Directives bekannt sind. Solche gibt's in Java nicht. Es steht Dir frei, einen der existierenden Präprozessoren für Java zu benutzen (google hilft), davon ist jedoch IMHO abzuraten. Oben stehende Vorschläge sind als Alternativen dazu gemeint.
Vor einigen Jahren hab ich mal ein Sun-Paper gelesen, in dem Begründungen zu diversen Sprach-Entscheidungen standen (u. a. C-style preprocessor directives, compile-time constants, labels/goto, etc.), ich finde's aber nicht wieder. Dieser Artikel geht ein bisschen in die Richtung: Java Tip 5: Java constants