Wann wird eine statische Membervariable/Field instantiiert

oraclin25

Erfahrenes Mitglied
Hallo zusammen,

Code:
public final class MeinPropertiesLoader extends PropertiesLoader{
    ...
    private static MeinPropertiesLoader meineInstanz = new MeinPropertiesLoader();
    
    private MeinPropertiesLoader(){
        super("Text");
    }

    public static MeinPropertiesLoader getMeineInstanz(){
        return meineInstanz; 
    }
    
    ...
}

Es geht um folgenden Aufruf:

Code:
MeinPropertiesLoader ratna = MeinPropertiesLoader.getMeineInstanz();

Es ist ein Aufruf zu einer statischen Methode, so dass dabei kein Objekt von der Klasse MeinPropertiesLoader erzeugt werden musste. Nur, der return-Wert dieser Methode bezieht sich auf eine statische Membervariable in der Klasse. Meine Frage:
Wann wird das tatsächliche Objekt von MeinPropertiesLoader erzeugt:
1. Bereits in dem Moment wenn MeinPropertiesLoader.getMeineInstanz(); von JVM verarbeitet wird
oder
2. In dem Moment, wo return meineInstanz dran ist. Sprich: in dem Moment wo der JVM merkt, dass zum Returnen das entsprechende Objekt benötigt wird.

Ooo jee, hoffentlich ist meine Frage verständlich.

Generell bin ich mir nicht sicher, ob bei einem "new" bereits alle ihre Membervariablen mit Objekten versehen werden:
Code:
RatnasKlasse ratnasObjekt = new RatnasKlasse();

Bestimmt oder? Die Membervariablen werden doch nicht erst mit Objekt definiert, wenn per Getter auf sie zugegriffen werden, oder?

Vielen Dank.

Viele Grüße aus Rheinland,

Eure Ratna
 
Hi

Keine Sorge, die Frage ist sehr verständlich :)

Kurzfassung: Keine Sorge, passt alles.

Langfassung:

Teil 1:
Ein ge-new-tes Objekt eines Klasse (was nichts mit static zu tun hat) führt als
erstes den Konstruktor aus, der natürlich den nicht-statischen Membervariablen
Werte zuweisen kann. Unter Anderem eben auch Objekte anderer Klassen.

Alle Konstruktorauswirkungen passieren genau zum new-Zeitpunkt,
nicht erst bei weiterer Verwendung der Variablen.

Sachen, die im Konstruktor keinen Wert bekommen, sind automatisch null (oder 0 für ints etc.).

Teil 2:
Gibt es zum new-Zeitpunkt noch unfertige statische Variablen werden die
VOR dem Start vom Konstruktor initialisiert. Es kann also nicht passieren,
dass man im Konstruktor unfertige statische Variablen verwendet.

Teil 3:
Ruft man (unabhängig von irgendwelchen Objekten) statische Methoden auf,
und es gibt noch unfertige statiche Variablen, werden die Variablen (wieder)
vor Methodenbeginn initialisiert. Auch hier keine Gefahr.

Teil 4:
Wenn man keine Objekte macht oder statische Methoden aufruft kann die Initialisierung von
statischen Variablen auch passieren, wenn man einfach auf die statische Variable zugreift
(Initialisierung genau vor Zugriff, eben falls noch uninitialisiert, klar).

Noch ein paar mehr Details gibts hier: http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1
Jedenfalls ist sichergestellt, dass eine statische Variable vor irgendeiner Verwendung davon fertig vorbereitet ist.

Auch mehrere Threads, die evt. gleichzeitig den Erstzugriff machen könnten, sind kein Problem
(solange man den normalen eingebauten Classloader verwendet).
 
Hallo sheel,

danke für die Antwort. Du hast den Aspekt Konstruktoren ins Thema genommen.
Ein ge-new-tes Objekt eines Klasse (was nichts mit static zu tun hat) führt als
erstes den Konstruktor aus, der natürlich den nicht-statischen Membervariablen
Werte zuweisen kann. Unter Anderem eben auch Objekte anderer Klassen.

Was ist aber, wenn es keinen dedizierten Konstruktor zur Initialisierung der Objekte von Membervariablen gibt?

Code:
public class EinfacheKlasse(){

      public static int zaehler = 5;
      
      DeutscheKlasse deutscheKlasse = new DeutscheKlasse();

}

Nach folgender Aufruf-Zeile im Außerhalb:
Code:
EinfacheKlasse ratna = new EinfacheKlasse();

, zeigt denn die Referenzvariable deutscheKlasse bereits auf ein DeutscheKlasse-Objekt?

Viele Grüße aus Rheinland,

Eure Ratna
 
Was ist aber, wenn es keinen dedizierten Konstruktor zur Initialisierung der Objekte von Membervariablen gibt?
Dann gilt folgender Satz für alle nicht-statischen Membervariablen:
Sachen, die im Konstruktor keinen Wert bekommen, sind automatisch null (oder 0 für ints etc.).
Zweiter Teil:
...zeigt denn die Referenzvariable deutscheKlasse bereits auf ein DeutscheKlasse-Objekt?
Ja.
Und die statische Variable zähler bekommt (spätestens) direkt vor dem "new EinfacheKlasse()" den Wert 5 zugewiesen.
 
Zurück