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 – StringVariablen und Array- Variablen.

Sowohl ein Array als auch ein String sind Objekte, die irgendwo im Speicher gespeichert sind. StringVariablen und Array-Variablen speichern nur Verweise auf Objekte.

Referenzvariablen in Java

int a, int b and double dsind primitive Variablen, die ihre Werte in sich selbst speichern.

Eine String strVariable ist eine Referenz und speichert die Adresse (Referenz) auf ein StringObjekt 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 kopiertdas 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.

Referenzen zuweisen

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
String hello = "Hello";
String s = hello;
Dies ist erlaubt
String hello = "Hello";
hello++;
Aber das ist nicht erlaubt
String hello = 0x1234;
Und das ist nicht erlaubt

4. Eine nullReferenz

Und was speichert eine Referenzvariable, wenn ihr noch nichts zugewiesen wurde?

Es speichert eine Nullreferenz . nullist ein spezielles Java-Schlüsselwort, das das Fehlen einer Referenz (eine leere Referenz) bedeutet. Der nullWert kann einer beliebigen Referenzvariablen zugewiesen werden.

Alle Referenzvariablen sind es, nulles sei denn, ihnen wurde eine Referenz zugewiesen.

Beispiele:

Code Beschreibung
class Person
{
   public static String name;
   public static int age;
}


Die String nameVariable hat einen Standardwert: null.
Die int ageVariable 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
String s = null;
s = "Hello";
s = null;
sGeschäfte null. speichert
seinen Verweis auf ein String-Objekt .
snull

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
class Solution
{
   public static void fill(String[] array, String value)
   {
      for (int i = 0; i < array.length; i++)
        array[i] = value;
   }

   public static void main(String[] args)
   {
     String[] data = new String[10];
     fill(data, "Hello");
   }
}


Das fillübergebene Array ( array) wird mit dem übergebenen Wert ( value) gefüllt.

fillBeim Aufruf der Methode arraywird dem Parameter eine Referenz auf das dataArray zugewiesen. Der valueVariablen wird eine Referenz auf das String-Objekt („Hello“) zugewiesen.

So sieht der Speicher vor dem Aufruf der fill Methode aus:

Übergabe von Referenzen auf Methoden

So sieht der Speicher aus, wenn die fill Methode ausgeführt wird :

Übergabe von Referenzen auf Methoden 2

Die Variablen dataund arrayverweisen auf denselben Container im Speicher (speichern Verweise darauf).

Die valueVariable 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.