Java Tutorial #15

Ist Java pass-by-value oder pass-by-reference?

Zur Frage, wie genau der Vorgang der Parameterübergabe bei Methoden abläuft, gibt es immer wieder Diskussionen. Wir gehen in diesem Artikel der Sache auf den Grund.

Stefan 03.12.2018

Infos zum Artikel

Kategorie Java
Autor Stefan
Datum 03.12.2018

Thema in Kurzform

  • Bei Parameter von primitiven Datentypen bedeutet pass-by-value, dass die Werte der übergebenen Argumente beim Methodenaufruf in die Parametervariablen kopiert werden.
  • Sind die Parameter Objektypen, bedeutet pass-by-value, dass die Verweise auf die Objekte kopiert werden.

pass-by-value bei primitiven Datentypen

Immer dann, wenn wir eine Methode mit Parameter aufrufen, werden die Werte der übergebenen Argumente in die Parametervariablen kopiert. Was das bedeutet, sehen wir hier:

public class Demo {

    public static void methodeMitParameter(int x){
        x += 2; // 3
    }

    public static void main(String[] args){
        int zahl = 1;
        methodeMitParameter(zahl);
        System.out.println(zahl); //1
    }
}

In der Main-Methode definieren wir zum Testen eine int-Variable zahl mit dem Wert 1. Wir rufen jetzt die statische Methode methodeMitParameter auf und übergeben als Argument die Variable zahl.

Jetzt geschieht Folgendes: Die Parametervariable x wird mit dem Wert von zahl initialisiert. Mit anderen Worten: Der Wert von zahl wird in x kopiert. Beide Variablen haben jetzt als Wert die Ganzzahl 1.

Aber: Es gibt keine Verbindung zwischen den beiden Variablen! Was auch immer innerhalb der Methode mit der Variablen x passiert: Es hat keine Auswirkungen auf die Variable zahl. Es sind zwei völlig voneinander unabhängige Variablen. Das sehen wir ja daran, dass sich der Wert von x in der Methode ändert (wird zu 3). Die Variable zahl geht das jedoch nichts an und sie behält ihren Wert 1.

Somit ist Pass-by-Value immer Pass-by-Copy.

pass-by-value bei Objekttypen

Etwas anders verhält es sich, wenn wir Methoden aufrufen, die Objekte als Argumente verlangen. Dann werden nicht die Objekte selbst, sondern die Verweise darauf kopiert. Man spricht hier auch von "Call-by-Value where the value is a reference".

Nach der Übergabe des Objekts in die Methode hat man also zwei Referenzvariablen, die beide auf dasselbe Objekte verweisen.

Schauen wir uns das mal praktisch an:

public class Metroid {

    public int energie = 10;

    public static void methodeMitParameter(Metroid mP){
        mP.energie = 20;
    }

    public static void main(String[] args){
        Metroid metroid = new Metroid();
        methodeMitParameter(metroid);
        System.out.println(metroid.energie); //20
    }

}

Die statische Methode verlangt beim Aufrufen mit dem Parameter mP ein Objekt der Klasse Metroid. In der Methode wird dann der Wert der Instanzvariable energie dieses Objekts auf 20 geändert.

Was geschieht genau, wenn wir die Methode aufrufen? Nicht das übergebene Objekt selbst wird kopiert, sondern die Referenz auf dieses Objekt. Es gibt nun zwei Referenzvariablen, die auf das eine Metroid-Objekt zeigen, nämlich die Variable mP (der Parameter) und die Variable metroid.

Bildlich kann man sich das Ganze so vorstellen:

Java pass by value

Beide Variablen können auf das Objekt unabhängig voneinander zugreifen und es verändern, denn beide verweisen darauf.

Übungen

einfach

Java arbeitet mit Pass by Value. Das wissen Sie jetzt. Worin liegen aber die Unterschiede der Parameterübergabe bei primitiven Typen und Objekttypen?

Lösung ein-/ausblenden

mittel

Was wird auf der Java-Konsole ausgegeben?

public class Samus {

    public static void modify(int x, int y){
        x = 3;
        y = 4;
    }

   public static void main(String[] args){

       int x = 1;
       int y = 2;
       System.out.println(" x = " + x + " ; y = " + y );
       Samus.modify(x,y);
       System.out.println(" x = " + x + " ; y = " + y );

    }

}
Lösung ein-/ausblenden

schwer

Sehen wir mal, ob Sie Pass-by-Value wirklich verstanden haben. Welche der folgenden Zeilen sind Teil des Outputs am Ende des Programms?

A. w1 = a
B. w1 = w1
C. s2 = s2
D. w2 = w2b
E.w3 = a
F.w3 = null
G.Compiler-Fehler

package paket1;

public class Waver {

    private String name;

    public Waver(String s){
        name = s;
    }

    public void append(String s){
        name += s;
    }

    public String getName(){
        return name;
    }

    public static Waver combine(Waver a, Waver b){
        a = new Waver("a");
        b.append("b");
        return a;
    }

}

package paket1;

public class Start {

    public static void main(String[] args){
        Waver w1 = new Waver("w1");
        Waver w2 = new Waver("w2");
        Waver w3 = Waver.combine(w1, w2);

        System.out.println("w1 = " + w1.getName());
        System.out.println("w2 = " + w2.getName());
        System.out.println("w3 = " + w3.getName());

    }
}
Lösung ein-/ausblenden

Primitive Datentypen

Am Ende des Kapitels werden Sie wissen, wie Primitive Datentypen korrekt eingesetzt werden.

Operatoren einsetzen

Es gibt eine Vielzahl an Operatoren. Wir haben eine Übersicht erstellt

Arrays in Java

Arrays ermöglichen das Speichern von Daten in einer übergeordneten Datenstruktur

FALCONBYTE.NET

Handmade with 🖤️

© 2018, 2019 Stefan E. Heller

Impressum | Datenschutz

facebook programmieren lernen twitter programmieren lernen youtube programmieren lernen