# If Debug in JAVA?



## Gast (12. Jan 2009)

geht sowas wie
#if Debug  (C#)
in JAVA?

danke & LG


----------



## SegFault (12. Jan 2009)

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. 

```
if (Options.getDebug() ) System.out.println(....);
```

direkte Präprozessordirektiven gehen nicht sind aber auch nicht wirklich von nöten.


----------



## Landei (12. Jan 2009)

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.


----------



## Marco13 (12. Jan 2009)

Manchmal ist das aber schon nachteilhaft

```
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

```
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....


----------



## ARadauer (12. Jan 2009)

warum glaubst du bietet die Logger Klasse von Log4J ein isDebugEnabled() ?


----------



## Murray (12. Jan 2009)

Marco13 hat gesagt.:
			
		

> Selbst wenn das logLevel besagt, dass garnichts ausgegeben wird, wird trotzdem der String gebaut.... :?
> Abhilfe sind da ggf. solche sachen wie
> 
> ```
> ...


Um die Log-Level zu berücksichtigen, kann man dann besser mit org.apache.log4j.Logger.isEnabledFor bzw. java.util.logging.Logger.isLoggable arbeiten:

```
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.


----------



## SegFault (12. Jan 2009)

Murray hat gesagt.:
			
		

> Die Variante mit der static final Konstante hat allerdings theoretisch den Vorteil, dass ein optimierender Compiler die gesamte Anweisung aus dem Code entfernen kann.



Womit wir wieder bei einer art Präprozessor direktiven wie bei C++ wären


----------



## Ebenius (12. Jan 2009)

Murray hat gesagt.:
			
		

> 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.


```
if (false) {
  throw new InternalError();
}
```


```
public static boolean DEBUG = false;
void foo() {
  if (DEBUG) {
    throw new InternalError();
  }
}
```


```
public interface Debug {
  static boolean DEBUG = false;
}

public class Test {
  void foo() {
    if (Debug.DEBUG) {
      throw new InternalError();
    }
  }
}
```

Grüße, Ebenius


----------



## Murray (12. Jan 2009)

Ebenius hat gesagt.:
			
		

> Im Regelfall sollte man darauf verzichten, und lieber die entsprechenden Methoden des Log-Frameworks (oder notfalls Systemvariablen) benutzen.


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

```
if ( testModus()) {
  /* mache etwas */
}
```
oder gar

```
if ( testModus()) {
  /* mache etwas */
} else {
  /* mache etwas anderes */
}
```
denn damit verhält sich das Programm im Testbetrieb ja anders als in Produktion


----------



## Gast (12. Jan 2009)

ihr wisst hoffentlich was mit #if debug gemeint ist ^^

bsp:
#if debug 
MessageBox.Show("asd");
#endif

dieser test wird nur in der Debug version ausgeführt und NICHT mitkompliert ....


----------



## Marco13 (12. Jan 2009)

Murray hat gesagt.:
			
		

> Die Variante mit der static final Konstante hat allerdings theoretisch den Vorteil, dass ein optimierender Compiler die gesamte Anweisung aus dem Code entfernen kann.


Darauf wollte ich mit meinem LOCAL_DEBUG hinaus. Wobei ich nicht weiß, wie Log4J das isDebugEnabled intern umsetzt.


----------



## Ebenius (12. Jan 2009)

Gast hat gesagt.:
			
		

> ihr wisst hoffentlich was mit #if debug gemeint ist ^^



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

Ebenius


----------

