Zum Inhalt springen
Java Anfänger 25 min

Parameter & Rückgabewerte

Tiefer Einblick in Parameter und Rückgabewerte in Java: Pass-by-Value, varargs, mehrere Rückgabewerte und Best Practices.

Aktualisiert:

Parameter & Rueckgabewerte

Im letzten Kapitel hast du die Grundlagen von Methoden gelernt. Jetzt tauchen wir tiefer ein: Wie funktionieren Parameter wirklich? Was passiert bei der Uebergabe? Und wie gibst du mehrere Werte zurueck?

Parameter im Detail

Parameter sind die Eingabewerte einer Methode. Sie werden beim Aufruf uebergeben:

// "name" und "alter" sind Parameter (formale Parameter)
static void begruesse(String name, int alter) {
    System.out.printf("Hallo %s, du bist %d Jahre alt!%n", name, alter);
}

public static void main(String[] args) {
    // "Max" und 25 sind Argumente (tatsaechliche Werte)
    begruesse("Max", 25);
    begruesse("Anna", 30);
}

Unterschied: Parameter vs. Argument

BegriffBedeutungBeispiel
ParameterVariable in der MethodendefinitionString name
ArgumentWert beim Methodenaufruf"Max"

Pass-by-Value in Java

Java arbeitet immer mit Pass-by-Value. Das bedeutet: Die Methode bekommt eine Kopie des Werts.

Bei primitiven Typen

static void verdopple(int zahl) {
    zahl = zahl * 2;
    System.out.println("In der Methode: " + zahl); // 20
}

public static void main(String[] args) {
    int x = 10;
    verdopple(x);
    System.out.println("Nach dem Aufruf: " + x); // 10 -- unveraendert!
}

Die Methode aendert nur ihre lokale Kopie — das Original bleibt gleich.

Bei Referenztypen

Bei Objekten wird die Referenz kopiert, nicht das Objekt selbst. Beide Referenzen zeigen auf dasselbe Objekt:

static void fuegeHinzu(List<String> liste, String element) {
    liste.add(element); // Aendert das ORIGINALE Objekt!
}

public static void main(String[] args) {
    var namen = new ArrayList<>(List.of("Max"));
    fuegeHinzu(namen, "Anna");
    System.out.println(namen); // [Max, Anna] -- veraendert!
}

Aber: Die Referenz selbst neu zuweisen hat keinen Effekt:

static void ersetze(List<String> liste) {
    liste = new ArrayList<>(); // Aendert nur die lokale Kopie der Referenz!
    liste.add("Neu");
}

public static void main(String[] args) {
    var namen = new ArrayList<>(List.of("Max"));
    ersetze(namen);
    System.out.println(namen); // [Max] -- unveraendert!
}

Visualisierung

Primitive:
main: x = [10]  -->  verdopple: zahl = [10] (Kopie)

Referenz:
main: namen = [Ref] ──┐
                       ├──> [Max, Anna]  (gleiches Objekt!)
fuegeHinzu: liste = [Ref] ──┘

Mehrere Parameter

Du kannst beliebig viele Parameter verwenden:

static double berechnePreis(String produkt, double einzelpreis, int menge, double rabatt) {
    var gesamt = einzelpreis * menge;
    var rabattBetrag = gesamt * rabatt;
    System.out.printf("%s: %.2f EUR (Rabatt: %.2f EUR)%n", produkt, gesamt - rabattBetrag, rabattBetrag);
    return gesamt - rabattBetrag;
}

public static void main(String[] args) {
    var preis = berechnePreis("Laptop", 999.99, 2, 0.10);
    System.out.printf("Endpreis: %.2f EUR%n", preis);
}

Best Practice: Wenn eine Methode mehr als 3-4 Parameter hat, ueberlege, ob du sie in ein Objekt zusammenfassen kannst:

// Statt vieler Parameter:
// static void erstelleBenutzer(String name, String email, int alter, String stadt, String beruf)

// Besser: Record verwenden
record BenutzerDaten(String name, String email, int alter, String stadt, String beruf) {}

static void erstelleBenutzer(BenutzerDaten daten) {
    System.out.println("Erstelle Benutzer: " + daten.name());
}

Varargs (Variable Argumente)

Mit ... kannst du eine variable Anzahl von Argumenten uebergeben:

static int summe(int... zahlen) {
    var ergebnis = 0;
    for (var zahl : zahlen) {
        ergebnis += zahl;
    }
    return ergebnis;
}

public static void main(String[] args) {
    System.out.println(summe(1, 2, 3));         // 6
    System.out.println(summe(10, 20));           // 30
    System.out.println(summe(1, 2, 3, 4, 5));   // 15
    System.out.println(summe());                 // 0
}

Regeln fuer Varargs:

  • Varargs muss der letzte Parameter sein
  • Es darf nur einen Varargs-Parameter pro Methode geben
  • Intern wird Varargs als Array behandelt
// OK: Varargs als letzter Parameter
static String formatiere(String prefix, String... namen) {
    return prefix + String.join(", ", namen);
}

// FEHLER: Varargs nicht am Ende
// static void falsch(String... namen, int alter) { }

Rueckgabewerte

Primitive Typen zurueckgeben

static int quadrat(int x) {
    return x * x;
}

static boolean istPositiv(double zahl) {
    return zahl > 0;
}

static char anfangsbuchstabe(String text) {
    return text.charAt(0);
}

Objekte zurueckgeben

static String formatiereName(String vorname, String nachname) {
    return nachname + ", " + vorname;
}

static List<Integer> geradeZahlen(int bis) {
    var ergebnis = new ArrayList<Integer>();
    for (int i = 2; i <= bis; i += 2) {
        ergebnis.add(i);
    }
    return ergebnis;
}

Mehrere Werte zurueckgeben

Java kann nur einen Wert zurueckgeben. Fuer mehrere Werte gibt es mehrere Strategien:

Option 1: Record verwenden (empfohlen)

record MinMax(int min, int max) {}

static MinMax findeMinMax(int[] zahlen) {
    var min = Integer.MAX_VALUE;
    var max = Integer.MIN_VALUE;

    for (var zahl : zahlen) {
        if (zahl < min) min = zahl;
        if (zahl > max) max = zahl;
    }

    return new MinMax(min, max);
}

public static void main(String[] args) {
    var ergebnis = findeMinMax(new int[]{3, 7, 1, 9, 4});
    System.out.println("Min: " + ergebnis.min()); // 1
    System.out.println("Max: " + ergebnis.max()); // 9
}

Option 2: Array zurueckgeben

static int[] teile(int a, int b) {
    return new int[]{a / b, a % b}; // [Quotient, Rest]
}

var ergebnis = teile(17, 5);
System.out.println("Quotient: " + ergebnis[0]); // 3
System.out.println("Rest: " + ergebnis[1]);     // 2

Option 3: Map zurueckgeben

static Map<String, Object> analysiereText(String text) {
    return Map.of(
        "laenge", text.length(),
        "woerter", text.split("\\s+").length,
        "grossbuchstaben", text.chars().filter(Character::isUpperCase).count()
    );
}

Methoden-Signatur

Die Signatur einer Methode besteht aus dem Namen und den Parametertypen:

// Verschiedene Signaturen:
static int addiere(int a, int b) { ... }        // addiere(int, int)
static double addiere(double a, double b) { ... } // addiere(double, double)
static int addiere(int a, int b, int c) { ... } // addiere(int, int, int)

Der Rueckgabetyp ist NICHT Teil der Signatur:

// FEHLER: Gleiche Signatur!
// static int verdopple(int x) { return x * 2; }
// static double verdopple(int x) { return x * 2.0; } // Kompilierfehler!

Rekursion

Eine Methode kann sich selbst aufrufen — das nennt man Rekursion:

static int fakultaet(int n) {
    if (n <= 1) return 1;     // Basisfall
    return n * fakultaet(n - 1); // Rekursiver Aufruf
}

System.out.println(fakultaet(5)); // 120 (5 * 4 * 3 * 2 * 1)
static int fibonacci(int n) {
    if (n <= 0) return 0;
    if (n == 1) return 1;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

for (int i = 0; i < 10; i++) {
    System.out.print(fibonacci(i) + " ");
}
// 0 1 1 2 3 5 8 13 21 34

Achtung: Rekursion braucht immer einen Basisfall, sonst gibt es einen StackOverflowError!

Uebungen

Uebung 1: Mathematik-Bibliothek

Schreibe Methoden fuer: min(int a, int b), max(int a, int b), abs(int x), potenz(int basis, int exponent).

Uebung 2: Array-Helfer

Schreibe Methoden: durchschnitt(double... zahlen), enthaelt(int[] array, int wert), umkehren(int[] array).

Uebung 3: Text-Analyse

Schreibe eine Methode analysiere(String text), die einen Record mit Wortanzahl, Zeichenanzahl und laengstem Wort zurueckgibt.

Uebung 4: Rekursives Palindrom

Schreibe eine rekursive Methode istPalindrom(String text), die prueft, ob ein Text ein Palindrom ist.

Was kommt als Naechstes?

In der naechsten Lektion lernst du Methoden-Ueberladung (Overloading) — wie du mehrere Methoden mit dem gleichen Namen, aber verschiedenen Parametern erstellen kannst.

Zusammenfassung

  • Java verwendet Pass-by-Value: Primitive werden kopiert, Referenzen werden kopiert (aber zeigen auf dasselbe Objekt)
  • Varargs (int... zahlen) erlauben eine variable Anzahl von Argumenten
  • Fuer mehrere Rueckgabewerte nutze Records oder Arrays
  • Die Signatur besteht aus Name + Parametertypen (nicht Rueckgabetyp)
  • Rekursion ist eine Methode, die sich selbst aufruft (braucht Basisfall!)
  • Halte die Parameteranzahl klein (max. 3-4) — sonst nutze Records

Pro-Tipp: Records (seit Java 16) sind die eleganteste Loesung, um mehrere Werte aus einer Methode zurueckzugeben. Statt unuebersichtliche Arrays oder Maps zu nutzen, definiere einfach record Ergebnis(int wert, String text) {} — und du hast einen sauberen, typsicheren Container mit automatischen Gettern, equals() und toString()!

Zurück zum Java Kurs