Was ist der Unterschied im Speicher zwischen einer Variablen, die null zugewiesen ist, und einer Variablen, die nicht zugewiesen ist?
Ich weiß, dass es einen Unterschied in der Nutzung gibt, aber was ist der Unterschied im Gedächtnis?
Was ist der Unterschied im Speicher zwischen einer Variablen, die null zugewiesen ist, und einer Variablen, die nicht zugewiesen ist?
Ich weiß, dass es einen Unterschied in der Nutzung gibt, aber was ist der Unterschied im Gedächtnis?
Antworten:
Es gibt keinen Unterschied zwischen den beiden "im Speicher".
Aus der Java-Sprachspezifikation, 4.12.5. Anfangswerte von Variablen :
Jede Variable in einem Programm muss einen Wert haben, bevor ihr Wert verwendet wird:
- Jede Klassenvariable, Instanzvariable oder Array-Komponente wird beim Erstellen mit einem Standardwert initialisiert (§15.9, §15.10.2):
...
- Für alle Referenztypen (§4.3) ist der Standardwert null.
...
- Eine lokale Variable (§14.4, §14.14) muss explizit einen Wert erhalten, bevor sie entweder durch Initialisierung (§14.4) oder Zuweisung (§15.26) auf eine Weise verwendet wird, die anhand der Regeln für die bestimmte Zuweisung (§14.26) überprüft werden kann 16 (definitive Zuordnung)).
Referenzvariablen auf Klassen- oder Objektebene wird ein Nullwert zugewiesen.
Referenzvariablen auf Methodenebene (Stapelebene) haben einen nicht angegebenen Wert (unter Verwendung des C ++ - Begriffs). In der Praxis ist dies häufig null, aber der Standard gibt nicht an, was in der Referenzvariablen enthalten ist, sondern nur, dass sie vor der Verwendung zugewiesen werden muss. Die Verwendung einer Referenzvariablen auf dem Stapel auf eine andere Weise als die Zuweisung als erste Verwendung führt zu einem Kompilierungsfehler.
if-then
Blocks initialisieren , teilt Ihnen der Compiler mit, dass die Variable im Code möglicherweise nicht initialisiert ist, wenn der then
Block nicht ausgeführt wird. Wenn Sie es initialisieren, null
kompiliert der Code. Warum ist das so, dass "eine Referenz, der nicht explizit ein Wert zugewiesen wurde, den Wert null hat" ?
null
da dies unnötige Arbeit wäre.
Was ist der Unterschied zwischen einer Variablen, die null zugewiesen ist, und anderen Variablen, die nicht im Speicher zugewiesen sind?
In Java gibt es keine nicht zugewiesene Variable. Klassendatenelementen, die keine explizite Zuweisung haben, wird der Standardwert für den Typ, null für ein Objekt oder 0 für primitive Typen zugewiesen.
Lokale Variablen befinden sich auf dem Stapel. (Nicht-primitive Einheimische, wie sie MyType foo
auch als Referenz auf dem Stapel leben.) Die Stapelzuordnung ist einfach. Wenn ein Block Deklarationen für lokale Variablen enthält, wird der von diesen lokalen Variablen benötigte Speicherplatz auf dem Stapel reserviert. Es ist unerheblich, ob diesen lokalen Variablen beim Anpassen des Stapels Werte zugewiesen werden, um diese lokalen Variablen aufzunehmen.
Es spielt keine Rolle, ob lokalen Variablen zum Zeitpunkt der Ausführung des Blocks ein Wert zugewiesen wird oder nicht. Ein Grund ist, dass sich die benötigte Größe nicht ändert. Grundelemente haben eine feste Größe, und Nicht-Grundelemente sind tatsächlich Referenzen. (Das referenzierte Objekt befindet sich auf dem Heap und nicht auf dem Stapel.) Der zweite Grund ist, dass die Verwendung einer lokalen Variablen, der kein Wert zugewiesen wurde, ein Kompilierungsfehler ist. Dies überlässt es der Java-Laufzeit, einer deklarierten, aber nicht zugewiesenen lokalen Variablen einen Wert (nicht unbedingt den Standardwert) zuzuweisen.
if-then
Blocks initialisieren , teilt Ihnen der Compiler mit, dass die Variable im Code möglicherweise nicht initialisiert ist, wenn der then
Block nicht ausgeführt wird. Wenn Sie es initialisieren, null
kompiliert der Code. Warum ist das so, dass "eine Referenz, der nicht explizit ein Wert zugewiesen wurde, den Wert null hat" ? Aber es ist mir immer noch nicht klar genug. Könnten Sie es mit anderen Worten erklären?
null
. Dies vereinfacht die Entwicklung des Java-Debuggers erheblich. Aber was ist, wenn Sie mit deaktiviertem Debug kompilieren? Jetzt ist diese Initialisierung unnötige zusätzliche Arbeit. Was sich in diesem Speicher befindet, ist irrelevant, da bekannt ist, dass der Speicher bei der ersten Verwendung einen gültigen Wert enthält.
Erstens müssen Sie sich wirklich keine Gedanken über den von lokalen Variablen verwendeten Speicherplatz machen. In einer Zeile kann ich ein Array von 100.000 Ganzzahlen zuweisen, das mehr Platz beansprucht als alle lokalen Variablen, die Sie jemals verwenden werden.
Zweitens wird Ihr Code von einem Compiler kompiliert, der wahrscheinlich clever ist. Wenn Ihre Variable nicht initialisiert ist, wird sie nicht verwendet (da der Compiler die Verwendung nicht initialisierter Variablen nicht zulässt). Aber wenn Sie es auf Null initialisieren, wird es immer noch nicht verwendet! Der Compiler wird leicht herausfinden, dass er nicht verwendet wird und überhaupt keinen Platz für die Variable verwendet. Selbst wenn es verwendet wird, kann der Compiler leicht herausfinden, dass der Wert Null ist, und anstelle der Variablen Null verwenden.
Aber drittens sind dies alles Mikrooptimierungen, die Ihnen in keiner Weise helfen werden, ein Programm zu optimieren. Sie versuchen, vier oder acht Bytes zu speichern. Konzentrieren Sie sich auf das Speichern von Megabyte, wenn Sie etwas speichern möchten.
Und während einige Leute behaupten, Variablen sollten immer initialisiert werden, trifft dies in Java nicht zu. Sie sollten eine Variable immer nur auf einen aussagekräftigen Wert setzen. Angenommen, Sie möchten eine Variable auf den Namen einer Person setzen und vergessen, dies in einem Codepfad zu tun. Wenn Sie die Variable blind auf Null initialisieren, kann der Compiler Ihnen dies nicht mitteilen. Ohne die Initialisierung kann und wird der Compiler Sie über Ihren Fehler informieren.