Initialisierung von Variablen

Status
Nicht offen für weitere Antworten.

flaffy

Mitglied
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.
 
Instanzvariablen haben immer ein Default-Wert.
Lokale Variablen werden (wegen der Performance) der default nicht initialisiert.
Es kommt also draufan, welche Variablen du betrachtest.

Code:
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).
 
gar nicht

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

und blockvariablen MÜSSEN initialisiert werden (hast du ja schon gemerkt)
 
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
 
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:
 
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
 
Ist jemand schon auf dieses Problem gestossen?
Code:
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. 😉
 
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:

Code:
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
 
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:
 
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
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben