Definition
Methode
In Java ist eine Methode ein benannter, in sich abgeschlossener Programmabschnitt innerhalb einer Klasse, der eine bestimmte Operation oder Aufgabe ausführt und optional Werte entgegennimmt (Parameter) und/oder zurückgibt (Rückgabewert).
Sondierende Methoden
Sondierende Methoden liefern beim Aufruf einen Wert an den Aufrufer zurück.
public class Circle { private int xPosition, yPosition, radius; public void setXPosition(int pXPos) { xPosition = pXPos; } public int getXPosition() { return xPosition; } public void moveRight() { xPosition += 50; } }
In diesem Quelltext sehen wir eine sondierende Methode, nämlich getXPosition(). Diese Methode liefert den Wert der Instanzvariable xPosition unverändert zurück. Solche sondierenden Methoden werden als Getter-Methoden bezeichnet, und sie beginnen immer mit der Silbe "get".
Getter-Methoden
Das sind sondierende Methoden, die den Wert von genau einer Instanzvariable unverändert zurückgeben.
Manipulierende Methoden
Der obige Quelltext enthält auch eine manipulierende Methode, nämlich setXPosition(). Diese Methode verändert den Wert der Instanzvariable xPosition. Der Parameter pXPos bringt dabei die erforderliche Information mit, um wie viele Pixel der Wert von xPosition verändert werden soll.
Man spricht hier auch von Botschaften, die an die Objekte einer Klasse gesendet werden. Durch Aufruf einer Methode wie
sonne.changeColor("yellow");
schickt man beispielsweise die Botschaft "Verändere die Farbe des Objektes nach Gelb" an das Objekt sonne der Klasse Circle.
Setter-Methoden
Das sind manipulierende Methoden, die genau eine Instanzvariable verändern.
In diesem Quelltext sehen wir zwei manipulierende und eine sondierende Methode.
Die manipulierende Methode setXPosition(int pXPos) verändert den Wert der Instanzvariable xPosition und wertet dazu den übergebenen Parameter pXPos aus. Es handelt sich hier um eine klassische Setter-Methode.
Die Methode moveRight() ist ebenfalls eine manipulierende Methode, aber keine Setter-Methode. Sie verändert den Wert der Instanzvariable xPosition um einen bestimmten, in der Methode festgelegten Wert. Ein Parameter ist hierfür daher nicht erforderlich.
Die Methode getXPos() schließlich ist eine sondierende Methode, genauer gesagt, eine Getter-Methode.
Andere Methoden
Konstruktoren
Konstruktoren sind besondere Methoden. Die Konstruktoren werden immer dann ausgeführt, wenn mit dem new-Befehl ein neues Objekt der Klasse erzeugt wird.
Bei dem Befehl
sonne = new Circle();
wird beispielsweise der Konstruktor der Klasse Circle aufgerufen und ausgeführt, und der Konstruktor sorgt dann dafür, dass ein neues Objekt der Klasse gebildet wird und den Namen "sonne" erhält.
Eine Klasse kann auch mehrere verschiedene Konstruktoren besitzen. Diese verschiedenen Konstruktoren müssen sich dann aber in ihren Parameterlisten unterscheiden, so dass der Compiler beim Übersetzen entscheiden kann, welcher der Konstruktoren auszuführen ist.
Ausgabemethoden
Neben den sondierenden und manipulierende Methoden gibt es noch Ausgabemethoden. Diese dienen zur Ausgabe von Texten und Graphiken.
public void show() { System.out.println("Radius: " + radius); System.out.println("Position: (" + xPosition + "," + yPosition + ")");} }
Hier sehen wir eine Methode, die den Radius und die Position eines Kreises auf die BlueJ-Konsole ausgibt.
Private Methoden, Hilfsmethoden
Öffentliche Methoden ("public") sind für das Verhalten einer Klasse bzw. ihrer Objekte zuständig. Es gibt aber auch Methoden, die nur intern von solchen öffentlichen Methoden benutzt werden, um bestimmte Aufgaben auszuführen, die für die Außenwelt uninteressant sind. Solche Hilfsmethoden werden mit dem Schlüsselwort "private" gekennzeichnet.
private void tausche(int a, int b) { int temp = zahl[a]; zahl[a] = zahl[b]; zahl[b] = temp; } public void bubblesort() { for (int d=1; d < MAX-1; d++) for (int i=0; i < MAX-1-d; i++) if ( zahl[i]) > zahl[i+1] ) tausche(i,i+1) }
Die öffentliche Methode bubblesort() benutzt hier beispielsweise die private Methode tausche(). Nach außen ist ist tausche() daher nicht sichtbar; jemand, der die Klasse benutzt, in der bubblesort() eine öffentliche Methode ist, kann nicht sehen, dass in der Klasse eine Methode namens tausche() existiert. Bei bubblesort() handelt es sich übrigens um eine manipulierende Methode, da die Instanzvariable zahl[], ein Array aus int-Zahlen, verändert wird. Von einer Setter-Methode würde man hier aber auf keinen Fall sprechen.
Clean Code: Methoden
Aus dem Buch "Clean Code" von Robert Martin (2009) fasse ich einmal das Wichtigste zusammen. Im Kapitel 3 stellt Martin Regeln vor, die man beim Schreiben von Funktionen (in Java also Methoden) berücksichtigen sollte.
1. Small!
"The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that."
Methoden sollen also möglichst klein sein. Das deckt sich auch gut mit den Grundprinzipien der OOP, nach denen jede Methode nach Möglichkeit nur eine konkrete Aufgabe erfüllen soll, und nicht zwei oder drei.
In den 80er Jahren - ich selbst habe diese Regel auch noch gelernt - sollte eine Funktion nicht größer sein als eine Bildschirmseite. Damals hatten wir noch Röhrenmonitore, die genau 24 Zeilen mit je 80 Zeichen darstellen konnten. Diese alte Regel wurde formuliert, damit man beim Betrachten einer Funktion nicht scrollen musste.
Heute gilt diese Regel natürlich nicht mehr. Moderne Monitore, vor allem wenn man sie in den Porträtmodus dreht, können locker 80 oder mehr Zeilen darstellen. Funktionen, die auf eine solche Seite passen, wären dann schon riesig groß.
Ich habe einmal versucht, diese erste Regel auf die Klasse Zeichnung des Shapes-Projektes von Barnes und Kölling anzuwenden. Hier zunächst das schlechte Beispiel:

Eine zu lange Methode
Dieses Bild zeigt den Konstruktor der Klasse SchlechteZeichnung, der völlig überladen ist. Ein Konstruktor sollte eigentlich nur die Instanzvariablen der Klasse initialisieren und dann vielleicht noch eine zentrale Methode aufrufen, die das ganze Programm in Gang setzt.
Der Konstruktor aus diesem schlechten Beispiel initialisiert die beiden Instanzvariablen, dann macht er die beiden Objekte sonne und mond sichtbar, und schließlich bewegt er das Objekt sonne, färbt es gelb und macht es größer. Das sind drei verschiedene Aufgaben, die dem Konstruktor hier zugemutet werden.
Hält man sich streng an die Prinzipien der OOP sowie an die erste Regel von Martin, dann könnte man folgenden Quelltext erhalten:

Vier kurze Methoden
Die drei Aufgaben des Konstruktors wurden auf insgesamt vier kurze Methoden verteilt.
- Die Methode makeVisible() macht die beiden Objekte sonne und mond sichtbar - mehr nicht.
- Die Methode draw() verändert die Eigenschaften des Objektes sonne - mehr nicht.
- Die Methode run() ruft diese beiden Methoden auf.
- Der Konstruktor initialisiert - wie erwartet - die Instanzvariablen und ruft dann die Methode run() auf. Stattdessen hätte man im Konstruktor auch makeVisible() und draw() aufrufen können, das wäre auch noch akzeptabel gewesen und der Quelltext wäre eine Methode kürzer.
2. Blocks and Indenting
Java-Blöcke mit if-else- oder while-Anweisungen sollten nur eine Zeile umfassen, und diese Zeile sollte im Idealfall aus einem Methodenaufruf bestehen. Wenn diese Methode dann auch noch einen sinnvollen Namen hat, ist im Grunde kein Kommentar mehr nötig, um die Funktion der if-else- oder while-Anweisung zu erklären.
Betrachten wir dazu wieder zwei Quelltexte, diesmal aus der Folge zum Sortieren von Zahlen.

Eine if-Bedingung mit drei Anweisungen
Die if-Bedingung enthält hier drei Anweisungen, die bewirken, dass die Zahl an der Position j mit der nächsten Zahl an Position j+1 vertauscht wird, falls die Zahl[j] größer ist als die Zahl[j+1].
Hält man sich an diese Regel von Martin, müsste der Quellcode so aussehen:

Eine if-Bedingung mit einer Anweisung
Das Tauschen der beiden Zahlen wurde nun in eine eigene Methode tausche() ausgelagert, deren Name schon eindeutig genug ist.
3. Do One Thing
"The following advice has appeared in one form or another for 30 years or more.
FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY."
Damit ist eigentlich schon alles gesagt, im Grunde deckt sich das auch mit der ersten Regel, nach der Funktionen möglichst klein sein sollten.
Auch die Methode bubblesortGut() macht nur "ONE THING", sie sortiert nämlich die Zahlen in dem Array daten[] aufsteigend. Und das macht die Methode gut (wenn auch recht langsam im Vergleich zu anderen Sortierverfahren). Allerdings gilt dies auch für die Methode bubblesortSchlecht(), die aber die Regel 2 verletzt.
4. One Level of Abstraction per Function
Den folgenden Abschnitt aus dem Buch von Martin habe ich mir von ChatGPT auf Deutsch zusammenfassen lassen, weil ich selbst Schwierigkeiten hatte, dem Gesagten zu folgen.
Zusammenfassung (ChatGPT)
Nur eine Abstraktionsebene pro Funktion:
Alle Anweisungen innerhalb einer Funktion sollten auf derselben Abstraktionsebene liegen. Werden hohe, mittlere und sehr niedrige Abstraktion vermischt (z. B. konzeptionelle Aufrufe wie getHtml() zusammen mit technischen Details wie .append("\n")), wird der Code unübersichtlich. Leser können schwer unterscheiden, was wesentlich und was nur Detail ist.
Stepdown-Regel (Top-Down-Prinzip):
Der Code sollte wie eine hierarchische Erzählung von oben nach unten lesbar sein. Jede Funktion beschreibt auf ihrer Ebene, was geschieht, und ruft Funktionen der nächsttieferen Ebene auf. So entsteht eine klare Struktur, die Funktionen kurz hält und sicherstellt, dass sie wirklich nur eine Aufgabe erfüllen.
Die Sache mit den Abstraktionsebenen ist vielleicht nicht so ganz klar. Schauen wir uns noch einmal den Quelltext des "guten" Bubblesort-Algorithmus an.

Eine if-Bedingung mit einer Anweisung
Die Methode bubblesortKomplett() beschreibt den gesamten Sortiervorgang auf einer konzeptionell höheren Abstraktionsebene: "Sortiere die Daten durch wiederholtes Vergleichen und Tauschen."
Die Methode tausche() hingegen arbeitet auf einer niedrigeren Abstraktionsebene: Sie kümmert sich um den technischen Detailvorgang, wie genau zwei Arrayelemente vertauscht werden.
5. Use Descriptive Names
Dass man einer Methode einen sinnvollen beschreibenden Namen gibt, sollte eigentlich eine Selbstverständlichkeit sein. Mehr zu den Namen von Bezeichnern findet sich auf der Seite "Bezeichner" in der Abteilung "Begriffe und Konzepte" dieser Homepage.
Die Namen von Methoden können durchaus recht lang sein - sie sollen ja möglichst genau beschreiben, was die Methode macht. Das Benutzen von Fachbegriffen kann den Namen wieder verkürzen. Eine Bubblesort-Methode könnte natürlich heißen
sortierenDurchVergleichenBenachbarterElementeUndGgfVertauschen()
Für Leute, die sich auch nur oberflächlich mit Informatik und Algorithmen auskennen, reicht natürlich bubbleSort(). Bei nicht so bekannten Verfahren sollte der Name aber durchaus länger und beschreibender sein.
6. Function Arguments
Martin schreibt, dass die ideale Anzahl von Parametern einer Methode 0 oder 1 ist. Zwei Parameter sind auch noch akzeptabel, bei dreien wird es schon kritisch, und mehr als drei Parameter sollten nur noch in sehr begründeten Ausnahmefällen verwendet werden.
Begründet wird dies nicht nur mit der besseren Lesbarkeit von Methoden, sondern auch mit dem einfacheren Testen solcher Methoden. Das haben Sie selbst schon festgestellt, als Sie mit BlueJ Methoden mit Parametern testen wollten.
Eine Methode wie moveRight() können Sie einfach mit der Maus anklicken und ausführen. Eine Methode wie moveHorizontal(int distance) können Sie in BlueJ auch mit der Maus aufrufen, müssen dann aber noch den Wert des Parameters eintippen. Und nun stellen Sie sich eine Methode vor wie
new Circle(int x, int y, int radius, String color)
Hier müssten Sie vier Daten eingeben, bevor die Methode gestartet werden kann.
Auch wenn Sie eine Testklasse schreiben, um verschiedene Methoden zu testen, ist es einfacher, wenn Sie Methoden ohne Parameter oder mit nur einem Parameter testen müssen. Stellen Sie sich die eben genannte Methode new Circle(int x, int y, int radius, String color) in einer Testumgebung vor. Um sicher zu stellen, dass die Methode wirklich funktioniert, müssten sie alle vier Parameter systematisch verändern, was viele Zeilen Quelltext in der Testumgebung benötigen würde.
Boolean-Parameter
Wenn eine Methode einen Parameter vom Typ boolean hat, ist das nach Martin kritisch. Denn eine solche Methode macht mehr als eine Sache. Wenn der Parameter true ist, macht sie die eine Sache, wenn der Parameter false ist, macht sie eine völlig andere Sache.
Objekte statt vieler Parameter
Betrachten Sie die Methode
public void checkAdresse(String vorname, String nachname, String strasse, int hausnr, int plz) { this.vorname = vorname; this.nachname = nachname; this.strasse = strasse; this.hausnr = hausnr; this.plz = plz; // eine ganze Reihe von Ueberpruefungen // die sicherstellen, dass die Adresse korrekt ist ... }
Hier ist es sinnvoller, statt der fünf Parameter, die für die Adresse stehen, ein Objekt einer eigenen Klasse Adresse zu übergeben:
public void checkAdresse(Adresse adresse) { this.adresse = adresse; // eine ganze Reihe von Ueberpruefungen // die sicherstellen, dass die Adresse korrekt ist ... }
6. Command Query Separation
"Functions should either do something or answer something, but not both. Either your function should change the state of an object, or it should return some information about that object. Doing both often leads to confusion."
Unter "professionellen" Java-Entwicklern ist es üblich, manipulierende Methoden mit einem Rückgabewert vom Typ boolean zu versehen, damit kontrolliert werden kann, ob die Methode tatsächliche ihre Aufgabe erfüllt hat. Martin nennt hier ein typisches Beispiel:
public boolean set(String attribute, String value)
Wenn die Operation erfolgreich war, gibt die Methode true zurück, andernfalls false. Betrachten wir dann folgenden Methodenaufruf:
if (set("username","unclebob")) ...
Da fragt sich doch jeder Leser und jede Leserin dieses Quelltextes, was das Ganze soll.
Martin schlägt dann vor, den manipulativen Teil des Befehl vom überprüfenden zu trennen:
if (attributeExists("username")) setAttribute("username","unclebob");
Am Ende des Kapitels gibt Martin noch viele weitere Ratschläge, auf die wir hier aber nicht weiter eingehen wollen; diese Webseite ist eh' schon lang genug.
Quellen:
- Lahres et al.: Objektorientierte Programmierung, Rheinwerk Computing 2021.
- Barnes, Kölling: Java lernen mit BlueJ - Objects first. Pearson-Verlag 2019.
- Ullenboom: Java ist auch eine Insel, Rheinwerk Computing 2023.
- Martin: Clean Code - A Handbook of Agile Software Craftmanship, Pearson Education 2009
- Balzert: Objektorientiert Programmieren, 4. Auflage, Springer-Verlag Berlin 2025.