Java-Methoden
Methoden in Java definieren und aufrufen — Rückgabetypen, Parameter und Methodenrumpf — um wiederverwendbaren Code zu strukturieren.
Eine Methode in Java ist ein benannter Codeblock, den Sie von anderen Stellen im Programm aus aufrufen können. Methoden helfen dabei, Wiederholungen zu vermeiden: Anstatt dieselbe Berechnung oder dieselbe fünfzeilige Operation dreimal zu schreiben, legen Sie sie in eine Methode und rufen diese dreimal auf.
Sie haben bereits eine Methode auf jeder Seite dieses Buches gesehen — main. Jedes Java-Programm ist lediglich eine Klasse mit mindestens einer Methode, die die JVM starten kann. In diesem Teil des Buches schauen wir uns an, wie Sie eigene Methoden schreiben.
Aufbau einer Methode
Eine Methodendeklaration besteht aus bis zu fünf Teilen: Modifikatoren, einem Rückgabetyp, einem Namen, einer Parameterliste und einem Rumpf.
public static int square(int n) {
return n * n;
}public static— Modifikatoren.publicsteuert die Sichtbarkeit;staticbedeutet, dass die Methode zur Klasse und nicht zu einer Instanz gehört. Wir werden auf beide in späteren Teilen eingehen; vorerst sind alle Methoden, die Sie in einer übergeordneten Hilfsklasse schreiben,public static.int— der Rückgabetyp. Die Art des Werts, den die Methode an ihren Aufrufer zurückgibt. Verwenden Sievoid, wenn sie nichts zurückgibt.square— der Name. Konventionell lowerCamelCase und ein Verb oder eine Verbphrase, die beschreibt, was die Methode tut.(int n)— die Parameterliste. Eingaben, die der Aufrufer bereitstellen muss. Jeder Parameter besteht aus einem Typ und einem Namen.{ ... }— der Rumpf. Der Code, der ausgeführt wird, wenn die Methode aufgerufen wird.
Eine Methode aufrufen
Einmal definiert, rufen Sie eine Methode auf, indem Sie ihren Namen gefolgt von (...) mit den Argumentwerten schreiben:
int result = square(7); // result is 49
System.out.println(square(3) + square(4)); // 9 + 16 = 25Der von der Methode zurückgegebene Wert kann wie jeder andere Ausdruck verwendet werden — einer Variablen zugewiesen, als Argument übergeben, ausgegeben oder mit etwas anderem kombiniert.
Die return-Anweisung
return tut zwei Dinge: Es beendet die Methode sofort und sendet einen Wert zurück an den Aufrufer.
public static int absolute(int n) {
if (n < 0) {
return -n;
}
return n;
}Sobald return -n ausgeführt wird, ist die Methode beendet — das zweite return n wird nicht ausgeführt. Eine Methode mit einem Nicht-void-Rückgabetyp muss auf jedem möglichen Codepfad einen Wert zurückgeben; der Compiler verweigert die Kompilierung, wenn ein Pfad fehlt.
Bei void-Methoden können Sie ein einfaches return; verwenden, um frühzeitig zu beenden, aber Sie müssen am Ende keins schreiben:
public static void greet(String name) {
if (name == null) return; // early exit
System.out.println("Hello, " + name);
} // implicit return at the closing braceParameter und Argumente
Die Namen in der Signatur der Methode sind Parameter; die Werte, die Sie an der Aufrufstelle übergeben, sind Argumente. Der Unterschied ist klein, aber es lohnt sich, ihn richtig zu verstehen:
public static int sum(int a, int b) { // a, b are parameters
return a + b;
}
int x = 3, y = 4;
int total = sum(x, y); // x, y are argumentsJeder Aufruf erhält eigene frische Kopien der Parameter. Das Zuweisen von a innerhalb von sum ändert x an der Aufrufstelle nicht. Das Kapitel über Pass-by-Value geht auf die Details ein.
Regeln für Rückgabetypen
Der Ausdruck nach return muss zuweisungskompatibel mit dem deklarierten Rückgabetyp sein — gleicher Typ oder ein Typ, den Java auf ihn erweitern kann:
public static double half(int n) {
return n / 2.0; // int / double → double, fine
}
public static int half(int n) {
return n / 2.0; // ERROR: double cannot be implicitly narrowed to int
}Wenn Sie wirklich einengen müssen, casten Sie explizit: return (int)(n / 2.0);.
Methoden können andere Methoden aufrufen
Der Rumpf einer Methode ist normaler Code — einschließlich Aufrufe anderer Methoden und sogar sich selbst (siehe Rekursion):
public static int square(int n) { return n * n; }
public static int sumOfSquares(int a, int b) {
return square(a) + square(b);
}Kleine, zielgerichtete Methoden zu schreiben und sie zu kombinieren ist der Kern von lesbarem Java-Code.
Zurückgeben ist nicht Ausgeben
Ein häufiger Anfängerfehler: Eine Methode, die einen Wert ausgibt, und eine Methode, die einen Wert zurückgibt, sind nicht austauschbar. return gibt einen Wert zurück, damit der Aufrufer ihn verwenden kann; System.out.println schreibt nur Text in die Konsole, und der Aufrufer erhält nichts.
public static void printSquare(int n) {
System.out.println(n * n); // shows the result, returns void
}
public static int square(int n) {
return n * n; // gives the result back to the caller
}Sie können das Ergebnis von square speichern, addieren oder weiterreichen, aber int x = printSquare(5); wird nicht kompilieren — printSquare gibt void zurück. Es empfiehlt sich, einen Wert zurückzugeben und den Aufrufer entscheiden zu lassen, ob er ihn ausgeben möchte; das hält die Methode wiederverwendbar.
Überladen: gleicher Name, andere Parameter
Java erlaubt es, dass zwei oder mehr Methoden denselben Namen haben, solange sich ihre Parameterlisten unterscheiden — in der Anzahl der Parameter oder ihren Typen. Dies wird als Überladen bezeichnet, und der Compiler wählt die richtige Methode anhand der übergebenen Argumente aus:
public static int max(int a, int b) { return a > b ? a : b; }
public static double max(double a, double b) { return a > b ? a : b; }
public static int max(int a, int b, int c) { return max(max(a, b), c); }max(3, 9) ruft die erste auf, max(2.5, 1.5) die zweite und max(4, 1, 7) die dritte. Der Rückgabetyp allein reicht nicht aus, um Überladungen zu unterscheiden — nur die Parameter zählen. Das Kapitel über Methodenüberladen behandelt die Übereinstimmungsregeln vollständig.
Wo Methoden leben
Eine Methode lebt immer innerhalb einer Klasse. Sie können keine eigenständige Funktion schreiben, wie es in JavaScript oder Python möglich ist. Die Klasse ist der Container; die Methode ist eines ihrer Mitglieder. Eine vollständige Datei mit zwei Methoden sieht so aus:
public class MathUtils {
public static int square(int n) {
return n * n;
}
public static int cube(int n) {
return n * n * n;
}
}Aus main in derselben Klasse würden Sie sie als square(5) und cube(2) aufrufen. Aus einer anderen Klasse würden Sie sie qualifizieren: MathUtils.square(5).
Ein ausgearbeitetes Beispiel
Was kommt als Nächstes
Jetzt, da Sie eine Methode deklarieren und aufrufen können, stellt sich die nächste Frage, wie Daten in sie hineinfließen. Das Kapitel über Parameter geht auf die Details ein — wie Argumente mit Parametern übereinstimmen, welche Typen erlaubt sind und was passiert, wenn der Aufrufer Objekte statt primitiver Typen übergibt.