3.6 Mit Referenzen arbeiten 

3.6.1 Zuweisungen bei Referenzen 

Eine Referenz erlaubt den Zugriff auf das referenzierte Objekt. Es kann durchaus mehrere Kopien dieser Referenz geben, die in Variablen mit unterschiedlichen Namen abgelegt sind – so wie eine Person (ein Personen-Objekt) von den Mitarbeitern als »Chefin« angesprochen wird, aber von ihrem Mann als »Schnuckiputzi«. Dies nennt sich auch Alias.
Wir wollen uns dies an einem Punkt-Objekt näher ansehen, das wir unter einem alternativen Variablennamen ansprechen wollen:
Point p = new Point(); Point q = p;
Ein Punkt-Objekt wird erzeugt und mit der Variablen p referenziert. Die zweite Zeile speichert nun dieselbe Referenz in der Variablen q. Danach verweisen p und q auf dasselbe Objekt.
Beispiel Dies hat zur Konsequenz, dass bei einer Änderung des Punkt-Objekts über die in der Variablen p gespeicherte Referenz die Änderung auch bei einem Zugriff über die Variable q beobachtet werden kann. Point p = new Point(); Point q = p; p.x = 10; System.out.println( q.x ); // 10 q.y = 5; System.out.println( p.y ); // 5 |
3.6.2 Methoden mit nicht-primitiven Parametern 

Dass sich das gleiche Objekt unter zwei Namen (über zwei verschiedene Variablen) ansprechen lässt, können wir gut bei Methoden beobachten. Eine Methode, die über den Parameter eine Objektreferenz erhält, kann auf das übergebene Objekt zugreifen. Das bedeutet: Die Methode kann dieses Objekt mit den angebotenen Methoden ändern oder auf die Attribute zugreifen.
Listing 3.4 InitPoint.java
import java.awt.*; public class InitPoint { static void clear( Point p ) { p.setLocation( 0, 0 ); } public static void main( String[] args ) { Point q = new Point( 47, 11 ); // Coordinates (x=47,y=11) clear( q ); System.out.println( q.x ); // 0 } }
In dem Moment, in dem main() die Funktion clear() aufruft, gibt es sozusagen die Namen q und p für das Objekt, wobei nur clear() das Objekt unter p kennt und main() nicht und clear() von dem Namen q keine Ahnung hat.
Hinweis Der Name einer Parametervariablen darf durchaus mit dem Namen einer lokalen Variablen übereinstimmen, was die Semantik nicht verändert. In unserem Fall hätte clear() die Point-Variable auch q nennen können. |
Wertübergabe und Referenzübergabe Call by Value
Primitive Variablen werden immer per Wert kopiert (engl. Call by Value). Das Gleiche gilt für Referenzen. Daher hat auch die folgende Funktion keine Nebenwirkungen:
static void clear( Point p ) { p = new Point(); }
Nach der Zuweisung referenziert die Variable p ein anderes Punkt-Objekt, und das an die Funktion übergebene Argument geht verloren. Diese Änderung wird nach außen hin nicht sichtbar, was bedeutet, dass der Aufrufer kein neues Objekt unter sich hat.
Call by Reference gibt es in Java nicht – ein Blick auf C und C++
In C++ gibt es eine weitere Argumentübergabe, die sich Call by Reference nennt. Würde eine Funktion wie clear() mit Referenzsemantik deklariert, würde die Variable p ein Synonym darstellen, also einen anderen Namen für eine Variable – in unserem Fall q. Damit würde die Zuweisung im Rumpf den Zeiger auf ein neues Objekt legen. Die swap()-Funktion ist ein gutes Beispiel für die Nützlichkeit von Call by Reference:
void swap( int& a, int& b ) { int tmp = a; a = b; b = tmp; }
Zeiger und Referenzen sind in C++ etwas anderes, was Spracheinsteiger leicht irritiert. Denn in C++ und auch C hätte eine vergleichbare swap()-Funktion auch mit Zeigern implementiert werden können:
void swap( int *a, int *b ) { int tmp = *a; *a = *b; *b = tmp; }
Die Implementierung gibt in C(++) einen Verweis auf das Argument.