Was ist der Unterschied zwischen einer nicht initialisierten Objektvariablen und einer in Java auf null initialisierten Objektvariablen?

12

Ich habe die folgenden zwei Objektvariablen

Date a;
Date b=null;

Auf jeden Fall beziehen sich sowohl 'a' als auch 'b' nicht auf Objekte.

Nun, wenn ich folgende Aussage aufrufe

System.out.println(a.toString());

Es wird ein Fehler bei der Kompilierung auftreten, wenn ich die folgende Anweisung aufrufe

System.out.println(b.toString());

Es wird kein Kompilierungsfehler auftreten, aber es wird ein Laufzeitfehler auftreten. Was ist der Grund dafür und welcher Wert wird tatsächlich in 'b' gespeichert, um einen Nullwert darzustellen?

Harish_N
quelle
2
bei SO oft gefragt und beantwortet: Warum werden lokale Variablen in Java nicht initialisiert? , Nicht initialisierte Variablen und Mitglieder in Java und in vielen damit verbundenen Fragen
Mücke
@gnat, beschäftigen sich andere Fragen mit dem Unterschied zwischen "nicht initialisiert" und "null"? Nur weil die Antwort ähnlich ist, heißt das nicht, dass es sich um eine doppelte Frage handelt.
DougM
@ DougM sicher, hast du die erste Frage gelesen, die ich angesprochen habe? "Gab es einen Grund, warum die Entwickler von Java der Meinung waren, dass lokalen Variablen kein Standardwert zugewiesen werden sollte? Wenn Instanzvariablen einen Standardwert erhalten können, warum können wir dann nicht dasselbe für lokale Variablen tun?" (FWIW es kann technisch gesehen kein Duplikat sein, einfach weil es an einem anderen Ort ist)
Mücke
1
Damit wird der Unterschied zwischen "nicht initialisiert" und "als null initialisiert" nicht angesprochen, sondern nur "warum werden Variablen nicht automatisch auf null initialisiert?" Gleiches Thema, etwas andere Frage.
DougM

Antworten:

3

Dies liegt daran, dass der Status lokaler Variablen innerhalb seines Bereichs gesteuert wird

 // method/loop/if/try-catch etc...
 {
   Date d; // if it's not intialised in this scope then its not intialised  anywhere
 }

Was bei Feldern nicht der Fall ist

class Foo{
 Date d; // it could be intialised anywhere, so its out of control and java will set to null for you
}

Warum ist es in Ordnung, eine Variable auf null zu setzen und sie sofort zu verwenden? Vielleicht ist das ein historischer Fehler, der manchmal zu schrecklichen Fehlern führt

 {
  Date d = null;
  try{
  }catch{ // hide it here 
  }
  return d;
 } 

Was ist nun der semantische Unterschied?

Date d;

gerade erklärt Variable, die eine Referenz, die auf ein Objekt des Typs aufnehmen kann Datejedoch

Date d= null; 

macht genau das gleiche, aber die Referenz zeigt diesmal auf null, null ist wie jede Referenz, es nimmt ein Leerzeichen eines nativen Zeigers ein, dh 4 Byte auf 32-Bit-Maschinen und 8 Byte auf 64-Bit-Maschinen

Sleiman Jneidi
quelle
Dies scheint lediglich den Punkt zu wiederholen, der in einer vorherigen Antwort vor einer Stunde gemacht und erklärt wurde
Mücke
@gnat Danke für Ihren Kommentar, aber ich glaube nicht,
Prost
Meinen Sie damit, dass null auch ein Objekt ist, das irgendwo im Speicher gespeichert ist und alle mit null zugewiesenen Objektvariablen auf dieses Nullobjekt zeigen.
Harish_N
@ Harish.N nein, das habe ich nicht gesagt, ich habe gesagt, es ist eine Referenz und kein Objekt
Sleiman Jneidi
In dem Beispiel, das Sie angegeben haben, ist 'd' eine Referenz. Es ist eine Referenz auf ein Objekt vom Typ Datum. Ebenso, wenn null eine Referenz ist. Auf welches Objekt bezieht es sich.
Harish_N
19

Es gibt keinen Unterschied für Klassenfelder. Sie sind nullstandardmäßig für Objekte, 0 für numerische Werte und falsefür Boolesche Werte .

Für in Methoden deklarierte Variablen erfordert Java, dass sie initialisiert werden. Wenn sie nicht initialisiert werden, tritt beim Zugriff auf die Kompilierung ein Fehler auf.

Was ist der Grund? Klassenfelder können mit jeder Methode geändert werden. In beliebiger Reihenfolge wird die Methode aufgerufen. Alle nicht privaten Felder können von anderen Klassen und / oder Klassen geändert werden, die diese Klasse erweitern. Daher macht es keinen Sinn, über eine nicht initialisierte Variable zu informieren, da sie an vielen, vielen Stellen zugewiesen werden kann.

Variablen in Methoden sind jedoch lokal und können nur innerhalb der Methode selbst geändert werden. Daher ist es sowohl möglich als auch rational, mögliche Fehler aufzuzeigen. Und der Compiler versucht es. Wenn es weiß, dass das Feld nicht initialisiert ist, wird ein Fehler angezeigt, da dies niemals gewünscht wird. Wenn es nicht sicher ist, wird eine Warnung ausgegeben, damit Sie sich vergewissern können.

public static class Test {
    Date a; // ok 
    Date b = null; // ok

    public void test() {
        Date c;
        Date d = null;

        System.out.println(a.toString());
        System.out.println(b.toString());
        System.out.println(c.toString()); // error
        System.out.println(d.toString()); // warning
    }
}
Dariusz
quelle