# Initialisierung von Variablen



## flaffy (13. Sep 2005)

Hallo 

Die Frage hört sich ein bischen doof an ... aber in wieweit beeinträchtigt die Initialisierung von Variablen die Performance? Ich komme eher aus der Microsoft Schiene und da wurde mir eingebläut das es zum guten Programmierton gehört sich nicht auf "Standardwerte" zu verlassen. Seitdem baue ich z.B. meine Beans wie folgt...

private String asdf1 = null;
private int asdf2 = 0;

Auf die Frage komme ich deswegen, zum einen da mir mein Compiler mal eine Warnung in Form von "Variable might have not been initialized yet" ausgegeben hat; und zum anderen weil ich mal mit einer Varialbe rechnen wollte, ein += ausgeführt habe und immer 0 zurück bekommen habe. Beim debuggen habe ich dann festgestellt das diese Variable eine Art NaN bzw. laut Dokumentation dies eine Art von "nicht initialisiert" darstellt.


----------



## Beni (13. Sep 2005)

Instanzvariablen haben _immer_ ein Default-Wert.
Lokale Variablen werden (wegen der Performance) der default _nicht_ initialisiert.
Es kommt also draufan, welche Variablen du betrachtest.


```
public class Blupp{
  private int test; // ist so ok
  private int test2 = 0; // ist mit der oberen Linie identisch

  public int doSomething(){
    int test; // kann ein Problem geben.
  }
}
```



> "Variable might have not been initialized yet"


Hm, das sollte keine Warnung sein. Zumindest mein Compiler sieht das als Fehler an (was es meist auch ist).


----------



## Bleiglanz (13. Sep 2005)

gar nicht

member variablen werden sowieso initialisiert (ist also eine reine Stilfrage)

und blockvariablen MÜSSEN initialisiert werden (hast du ja schon gemerkt)


----------



## Mag1c (13. Sep 2005)

Hi,

ja, doch, das tut sie doch. (Bzw. ich weiß nicht, ob und welche Compiler das wegoptimieren.)
Normalerweise werden solche Initialisierungen tatsächlich durch Befehle ausgeführt.
Aber wie hier schon erwähnt wurde, sind Instanzvariablen mit Default-Werten belegt,
sodaß man sich solche Initialisierungen sparen kann (und damit auch ein winziges bisschen Performance gewinnt  )

Gruß
Mag1c


----------



## Beni (13. Sep 2005)

Glaubst du der Defaultwert kommt aus dem Nichts?
Glaubst du ernsthaft, da wäre ein Performancegewinn der über 1 Nanosekunde hinausgeht?

Optimier erst wenn du siehst, dass es zu langsam ist. Und vorallem: optimier dort, wo es sich lohnt :wink:


----------



## Mag1c (13. Sep 2005)

Hi,

mir gings hier nur ums Prinzip. Und da wir ja hier korrekte Informationen weitergeben
wollen, habe ich das mal richtig gestellt. Ob da ein Performancegewinn tatsächlich messbar
ist, ist mir ehrlich gesagt wurscht 8)

Gruß
Mag1c


----------



## flaffy (14. Sep 2005)

So ungefähr hatte ich mir das auch gedacht - Danke für eure Antworten


----------



## Guest (14. Sep 2005)

Ist jemand schon auf dieses Problem gestossen?
	
	
	
	





```
public class Test {

  public static void main(String[] args) {

    abstract class A {

      public A() {
        init();
      }

      protected abstract void init();
    }
    
    class B extends A {

      private int i=10;
      
      public B() {
        super();
      }
      
      protected void init() {
        System.out.println(i); // Was wird hier ausgegeben? ;)
      }
    }
    
    new B();
  }
}
```
Hat mich mal paar graue Haare gekostet, bis ich den Debugger
angeschmissen habe. Ich habe eine abstrakte Klasse aus einem Framework 
überschrieben, die eine Initialisierung in der oben angegebenen Form
anstösst. Lokale Variablen bzw. Instanzvariablen werden aber erst nach dem
Konstruktor initialisiert. Schön doof, was? 
Solchen Fehler macht man nur einmal.


----------



## Mag1c (14. Sep 2005)

Hi,

jaaa ... Moment mal ... nicht so schnell ... 

das ganze ist nämlich noch Compiler-abhängig. Bei dem einen Compiler werden die
Instanz-Variablen nach dem Konstruktor initialisiert. Bei einem anderen Compiler
geschieht das vor dem Konstruktor (also zwischen Objekterzeugung und Ausführung
des Konstruktor-Codes). So liefert dann der folgende Code Compiler-abhängig
unterschiedliche Ergebnisse:


```
public class Test {
    private int zahl = 0;

    public Test () {
        zahl = 1;
    }
}
```

(Allerdings sind meine Erfahrungen diesbezüglich schon ein paar Tage alt. Könnte
sein, daß sich die Compiler-Bauer inzwischen auf eine Variante geeinigt haben)

Gruß
Mag1c


----------



## Guest (15. Sep 2005)

Das hat nichts mit dem Compiler zu tun, es ist "normales" Laufzeitverhalten der JVM.
Zuerst wird die Super-Instanz initialisiert, erst dann kommt es zurück zur überschreibenden
Instanz, wo die Instanzvariablen initialisiert werden und der Code des Konstruktors
ausgeführt wird.
In Deinem Beispiel ist keine Vererbungshierarchie im Spiel.

Wie auch immer, es ist gut sowas zu wissen, sonst wundert man sich, wenn einem
die Anwendung um die Ohren fliegt. :wink:


----------



## Bleiglanz (15. Sep 2005)

> das ganze ist nämlich noch Compiler-abhängig. Bei dem einen Compiler werden die
> Instanz-Variablen nach dem Konstruktor initialisiert. Bei einem anderen Compiler
> geschieht das vor dem Konstruktor



hä? das dürfte nicht stimmen, das ganze Procedere ist in Java genau vorgeschrieben, da sollten eigentlich alle Compiler das gleiche machen...

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.5


----------



## Mag1c (15. Sep 2005)

Hi,

ja war klar, daß es da Proteste gibt  Hab aber nur meine Erfahrungen wiedergegeben.
Wir haben mal vor einiger Zeit nach einem Fehler gesucht, der nur bei Verwendung
des einen Compilers auftrat. Beim anderen Compiler gings es. Grund war eben
das von mir oben beschriebene Verhalten.

Ja, es kann durchaus sein, daß das ein Fehler im Compiler war, keine Ahnung. Vielleicht
war auch damals der Ablauf noch nicht ganz so festgelegt (ist inzwischen 4 Jahre her).

Gruß
Mag1c


----------

