Wie genau erfolgt eigentlich die Parameterübergabe bei Java?

Zur genauen Beantwortung dieser Frage muss die Übergabe von primitiven und Referenztypen gesondert betrachtet werden. Generell gilt jedoch, dass beim Methodenaufruf der Wert der Variablen, nicht deren Speicherort (Referenz) übergeben wird (‘call by value’).

Übergabe primitiver Werte

Beim Aufruf einer Methode wird ein formaler Parameter (formal parameter) vor der Übergabe an die Methode selbst validiert und dann das Ergebnis als tatsächlicher Parameter (actual parameter) an die Methode weitergeleitet. Die dortige Verwendung hat keinen Einfluss auf den Wert des formalen Parameters. Das zeigt das folgende Beispiel:

public class Parameteruebergabe {

    public static void main(String[] args) {
        int i = 10;
        System.out.println(paramChange(i));    // 2.5
        System.out.println(i);                // 10
    }
    
    private static double paramChange(double d){
        d = d/4;
        return d;
    }
}

Die int-Variable i wird als formaler Parameter dem Aufruf der Methode paramChange(double d) übergeben. Vor der Weitergabe an die Methode selbst findet ein casting zum double-Wert statt, da dieser Typ vom tatsächlichen Parameter verlangt wird. Innerhalb der Methode findet eine einfache Division statt, die den Wert des lokalen tatsächlichen Parameters ändert. Nach Beendigung des Methodendurchlaufs sind weder der Wert der Variablen i, noch deren Typ geändert.

Übergabe von Referenzwerten

Beim folgenden Beispiel wird ein Objekt vom Typ Ball erzeugt, das zunächst die Eigenschaft Handball hat. Die Methode wandel(Ball ball) ändert dies zum Typ Golfball. Diese Änderung ist dauerhaft, bezieht sich also nicht nur auf den tatsächlichen Parameter. Das anschließende Setzen des Parameters auf null zeigt, dass hier tatsächlich der Wert, nicht die Referenz selbst geändert wurde.


public class Parameteruebergabe {

    public static void main(String[] args) {
        Ball meinBall = new Ball();
        System.out.println("Ball vor dem Wandel: " + meinBall.typ);    // Handball
        wandel(meinBall);
        System.out.println("Ball vor dem Wandel: " + meinBall.typ);    // Golfball
    }
    
    private static void wandel(Ball ball){
        ball.typ = "Golfball";
        ball = null;
    }
}

class Ball {
    String typ = "Handball";
}