1. Referenzvariablen
In der Java-Sprache gibt es zwei Arten von Variablen: primitive Variablen und alles andere. Wie es der Zufall will, werden wir jetzt über „alles andere“ reden.
Tatsächlich wäre es richtiger zu sagen, dass es primitive Variablen und Referenzvariablen gibt . Was sind also diese Referenzvariablen?
Im Gegensatz zu primitiven Typen, deren Variablen Werte direkt speichern, speichern Referenzvariablen Verweise auf Objekte. Das heißt, es gibt irgendwo im Speicher ein Objekt und die Referenzvariable speichert einfach die Adresse dieses Objekts im Speicher (eine Referenz auf das Objekt).
Nur primitive Typen speichern Werte direkt in Variablen. Alle anderen Typen speichern nur eine Objektreferenz . Übrigens sind Ihnen bereits zwei solcher Arten von Variablen begegnet – String
Variablen und Array- Variablen.
Sowohl ein Array als auch ein String sind Objekte, die irgendwo im Speicher gespeichert sind. String
Variablen und Array-Variablen speichern nur Verweise auf Objekte.
int a, int b and double d
sind primitive Variablen, die ihre Werte in sich selbst speichern.
Eine String str
Variable ist eine Referenz und speichert die Adresse (Referenz) auf ein String
Objekt im Speicher.
Wenn einer Variablen eines primitiven Typs ein primitiver Wert zugewiesen wird, wird ihr Wert kopiert (dupliziert). Bei der Zuweisung einer Referenzvariablen wird nur die Adresse des Objekts kopiert – das Objekt selbst wird nicht kopiert .
2. Was hat es mit Referenzen auf sich?
Was ist der grundlegende Unterschied zwischen Referenzvariablen und primitiven Variablen?
Eine primitive Variable ist wie eine Box: Sie können darin einen Wert speichern. Eine Referenzvariable ähnelt eher einem Blatt Papier mit einer Telefonnummer darauf.
Ein Auto vs. Schlüssel zum Auto
Stellen Sie sich vor, Sie beschließen, Ihrem Freund zum Geburtstag ein Auto zu schenken. Man packt es nicht in einen Karton und trägt es mit sich herum: Dafür ist das Auto zu groß.
Es ist viel bequemer, nur die Autoschlüssel in einer Box zu präsentieren, die groß genug ist, um sie aufzunehmen. Ihr Freund wird alles verstehen, wenn er die Schlüssel aus dem Kasten holt. Sie müssen nicht das ganze Auto mit sich führen, sondern können einfach die Schlüssel abgeben.
Eine Person vs. ihre Telefonnummer
Oder hier ist ein anderer Vergleich: eine Person und ihre Telefonnummer. Eine Telefonnummer ist nicht die Person, aber eine Telefonnummer kann verwendet werden, um sie anzurufen, sie um Informationen zu bitten oder Anweisungen zu geben.
Ebenso wird eine Referenz verwendet, um mit einem Objekt zu interagieren. Alle Objekte interagieren über Referenzen miteinander. Statt „Personen auszutauschen“, tauschen wir einfach Telefonnummern aus.
Wenn einer primitiven Variablen ein Wert zugewiesen wird, wird ihr Wert kopiert (dupliziert). Beim Zuweisen eines Werts zu einer Referenzvariablen wird nur die Adresse (Telefonnummer) des Objekts kopiert – das Objekt selbst wird nicht kopiert.
Eine Referenz bietet einen weiteren Vorteil: Sie können eine Objektreferenz an eine Methode übergeben, und die Methode kann das Objekt modifizieren (ändern), indem sie die Referenz darauf verwendet, ihre Methoden aufruft und auf Daten innerhalb des Objekts zugreift.
3. Referenzen zuweisen
Bei der Zuweisung von Referenzvariablen wird nur die Adresse des Objekts im Speicher zugewiesen. Objekte selbst erscheinen oder verschwinden nicht.
Dieser Ansatz vermeidet das Kopieren großer Speichermengen. Wenn Sie ein sehr großes Objekt an eine Methode übergeben müssen, übergeben wir einfach die Objektreferenz und das war’s. Die Referenz nimmt viel weniger Platz ein.
Die Größe aller Referenzvariablen (unabhängig von ihrem Typ) ist gleich – 4 Bytes (wie ein int). Aber! Wenn Ihre Anwendung auf einer 64-Bit-Java-Maschine ausgeführt wird, haben alle Referenzen eine Größe von 8 Byte (64 Bit).
Darüber hinaus können Referenzen nur einander zugeordnet werden. Sie können Referenzen nicht ändern oder Referenzvariablen beliebige Werte zuweisen:
Code | Beschreibung |
---|---|
|
Dies ist erlaubt |
|
Aber das ist nicht erlaubt |
|
Und das ist nicht erlaubt |
4. Eine null
Referenz
Und was speichert eine Referenzvariable, wenn ihr noch nichts zugewiesen wurde?
Es speichert eine Nullreferenz . null
ist ein spezielles Java-Schlüsselwort, das das Fehlen einer Referenz (eine leere Referenz) bedeutet. Der null
Wert kann einer beliebigen Referenzvariablen zugewiesen werden.
Alle Referenzvariablen sind es, null
es sei denn, ihnen wurde eine Referenz zugewiesen.
Beispiele:
Code | Beschreibung |
---|---|
|
Die String name Variable hat einen Standardwert: null . Die int age Variable hat einen Standardwert: 0 . |
Lokale Variablen, denen kein Wert zugewiesen wurde, gelten sowohl für primitive als auch für Referenztypen als nicht initialisiert.
Wenn eine Variable einen Verweis auf ein Objekt speichert und Sie den Wert der Variablen löschen möchten, weisen Sie ihr einfach einen Nullverweis zu.
Code | Beschreibung |
---|---|
|
s Geschäfte null . speichert s einen Verweis auf ein String-Objekt .s null |
5. Übergabe von Referenzen an Methoden
Wenn eine Methode über Parameter verfügt, die Referenztypen sind , werden Werte auf die gleiche Weise an die Methode übergeben wie bei der Arbeit mit Nicht-Referenzvariablen. Dem Parameter wird einfach der Wert der anderen Variablen zugewiesen.
Beispiel:
Code | Beschreibung |
---|---|
|
Das fill übergebene Array ( array ) wird mit dem übergebenen Wert ( value ) gefüllt. |
fill
Beim Aufruf der Methode array
wird dem Parameter eine Referenz auf das data
Array zugewiesen. Der value
Variablen wird eine Referenz auf das String-Objekt („Hello“) zugewiesen.
So sieht der Speicher vor dem Aufruf der fill
Methode aus:
So sieht der Speicher aus, wenn die fill
Methode ausgeführt wird :

Die Variablen data
und array
verweisen auf denselben Container im Speicher (speichern Verweise darauf).
Die value
Variable speichert einen Verweis auf das String-Objekt ( "Hello"
).
Die Zellen des Arrays speichern außerdem lediglich Verweise auf das "Hello"
Objekt.
Tatsächlich werden keine Objekte dupliziert – nur Referenzen werden kopiert.
6. Vergleich mit der Sprache C/C++
In Interviews werden Java-Programmierer manchmal gefragt, wie Daten an Methoden in Java übergeben werden. Und manchmal stellt sich die Frage, ob Daten als Referenz oder als Wert übergeben werden.
Diese Frage stammt aus C++, ist aber in Java nicht sehr aussagekräftig . In Java werden Parametern immer einfach die Werte der Argumente zugewiesen. Die richtige Antwort wäre also „ nach Wert “.
Seien Sie jedoch darauf vorbereitet, Ihren Standpunkt zu erläutern , da Sie möglicherweise sofort die Antwort hören: „Primitive Typen werden als Wert übergeben, und Referenztypen werden als Referenz übergeben.“
Der Grund für dieses Problem liegt in der Tatsache, dass viele Java-Programmierer in der Vergangenheit C++-Programmierer waren. In dieser Programmiersprache war die Frage, wie Parameter an Methoden übergeben werden, sehr wichtig.
In Java ist alles eindeutig: Primitive Typen speichern Werte und Referenztypen speichern auch einen Wert – eine Referenz. Es geht darum, ob eine Variable als Wert betrachtet wird .
In C++ könnte eine Variable sowohl einen Verweis auf ein Objekt als auch das Objekt selbst speichern. Das Gleiche galt für primitive Typen: Eine primitive Variable konnte einen Wert speichern oder die Variable als Referenz auf eine deklarieren int
. Um Verwirrung zu vermeiden, bezeichnen C++-Programmierer das Objekt einer Referenz immer als Referenz und das Objekt selbst als Wert.
In C++ könnte es leicht vorkommen, dass eine Variable ein Objekt enthält, die andere jedoch einen Verweis auf dieses Objekt. Dementsprechend war die Frage, was eine Variable speichert – das Objekt selbst oder nur eine Referenz darauf – sehr wichtig. Wenn ein Objekt an eine Methode übergeben wurde, wurde es kopiert (bei Übergabe als Wert) und nicht kopiert (bei Übergabe als Referenz).
In Java existiert diese Dualität nicht, daher lautet die richtige Antwort: Argumente werden als Wert an Java-Methoden übergeben . Es ist nur so, dass dieser Wert eine Referenz ist, wenn wir über Referenzvariablen sprechen.
GO TO FULL VERSION