Methode (Java)
In Java ist eine Methode eine sequenzielle Sammlung von ausführbaren Befehlen.
Methoden müssen stets in einer Klasse oder einem Interface definiert werden. Zur Laufzeit gehört eine normale Methode dann zu einem Objekt, und hat lesenden und schreibenden Zugriff auf das Objekt. Ausnahme sind sog. "statische Methoden" welche zu keinem Objekt gehören.
Inhaltsverzeichnis
Syntax
Eine Methode besteht aus einem Kopf und einem Rumpf. Der Kopf stellt die Schnittstelle zur Aussenwelt dar, der Rumpf hingegen ist der Code, der tatsächlich ausgeführt wird. <code=java>Kopf{
Rumpf
}</code=java> Der Kopf ist stets vor dem Rumpf, der Rumpf stets durch geschweifte Klammern gekennzeichnet.
Methodenkopf
Der Kopf besteht, von links nach rechts, aus folgenden Elementen:
- verschiedene Modifier (optional)
- Definitionen lokaler Generics (optional)
- Typ der Rückgabe (erforderlich)
- Name der Methode (erforderlich)
- Liste der Argumente (erforderlich)
- Liste von Ausnahmen (optional)
Ein Beispiel: <code=java>public static <X> X getRandom( List<X> list ) throws ListEmptyException;</code=java>
Die Modifier sind hier "public static", es gibt ein Generic "X", die Rückgabe der Methode ist ein Objekt des Types "X", die Methode heisst "getRandom", erwartet wird ein Argument "list" vom Typ "List<X>", und die Methode kann eine "ListEmptyException" werfen, falls die Liste leer ist.
Modifier
Als Modifier sind die bekannten Sichtbarkeits-Modifier "public", "protected" und "private" erlaubt. Die Effekte von "static", "final" und "abstract" sind weiter unten in diesem Artikel erklärt. Mit "synchronized" kann dem aufrufenden Thread exklusiver Zugriff auf das Objekt, auf dem die Methode aufsetzt, gegeben werden.
Lokale Generics
In spitzen Klammern geschrieben, und mit Komma getrennt, können beliebige Generics definiert werden. Diese Generics können dann in der gesammten Methode verwendet werden.
Rückgabetypen
Eine Methode kann einen Wert an den Aufrufer zurückgeben. Dabei ist jeder Typ erlaubt, egal ob Klasse, Generic oder primitiver Datentyp. Falls eine Methode kein Rückgabe hat, wird dies mit dem Schlüsselwort "void" angezeigt: <code=java>public void hide();</code=java>
Methodennamen
Der Name einer Methode muss mit einem Buchstaben beginnen, danach können Buchstaben, Ziffern und einige Sonderzeichen folgen.
Üblicherweise beginnen Namen mit einem Kleinbuchstaben, und sind Verben.
Argumente
Die Argumente sind Variablen die der Aufrufer der Methode ausfüllen muss. Die Argumente werden durch eine Komma-getrennte Liste von "Typ"-"Namen"-Paaren angegeben. Diese Argument-Liste wird in runden Klammern geschrieben.
Falls eine Methode keine Argumente benötigt, so schreibt man einfach "()" als Argumentliste.
Argumente werden stets bei call-by-value übergeben.
Beispiele: Eine Methode die zwei int-Argumente benötigt: <code=java>public int max( int a, int b );</code=java>
Eine Methode ohne Argumente: <code=java>public int max();</code=java>
Ausnahmen
Methoden können Exceptions werfen. Die checked-Exceptions müssen aufgelistet werden, dazu wird das Schlüsselwort "throws" verwendet.
Beispiel: Eine Methode die zwei unterschiedliche Exceptions werfen kann: <code=java>public void writeFile( String path )
throws NoSuchFileException, ReadOnlyFileException;</code=java>
Methodenrumpf
Variablen
Innerhalb des Rumpfes kann man jederzeit neue Variablen definieren, und ihnen Werte zuweisen. <code=java>// neue Variablen int x; int y = 4;
// Zuweisung x = y + 1;</code=java> Die Variablen sind ausserhalb der Methode nicht sichtbar.
Verzweigungen
Mit if-else können Verzweigungen in den ausgeführten Code eingebaut werden. Beispiel: hier wird der Variable "z" stehts der kleinere Wert der beiden Variablen "x" und "y" zugewiesen: <code=java>if( x < y ){
z = x;
} else{
z = y;
}</code=java>
Schleifen
Die verschiedenen Schleifen von Java können benutzt werden. Dies sind while, do-while, for und for-each.
Ausnahmen
Sollte eine Ausnahme, ein Ereignis, das die korrekte Beendingung der Methode verhindert, auftreten, so kann eine Exception geworfen werden. Hierzu wird das Schlüsselwort "throw" benutzt: <code=java>if( !file.exists() )
throw new NoSuchFileException( file.getPath() );
</code=java>
Klassen / Interfaces
Innerhalb einer Methode können auch ganze Klassen oder Interfaces definiert werden. Mit Ausnahme der anonymen Klassen ist es aber höchst ungewöhnlich, so etwas zu tun.
Rücksprung
Sofern ein Rückgabewert definiert wurde (also nicht "void" ist), und die Methode keine Endlosschleife besitzt, muss mit "return" ein Wert an den Aufrufer zurückgegeben werden.
Beispiel: hier wird der Wert der Variable "x" zurückgegeben: <code=java>return x;</code=java>
Eine Methode kann auch mehrere return-Befehle besitzen, allerdings wird immer nur einer ausgeführt. Der return-Befehl ist stets der letzte Befehl der ausgeführt wird, sämtliche nachfolgenden Befehle werden ignoriert.
Falls der Rückgabetyp "void" ist, kann man return einfach verwenden, um aus der Methode zu springen: <code=java>return;</code=java>
Aufruf
Beim Aufruf einer Methode müssen alle Argumente der Methode ausgefüllt werden. Lokale Generics werden vom Compiler automatisch berechnet, und der Rückgabewert kann ignoriert werden.
Ein Aufruf kann z.B. so aussehen: <code=java>int summe = plus( 23, 47 );</code=java> Hier wird die Methode "plus" mit den Argumenten "32" und "47" aufgerufen. Die Rückgabe von "plus" wird in der Variable "summe" gespeichert.
Da normale Methoden zu einem Objekt gehören, muss man oft das Objekt angeben, auf dem die Methode laufen wird: <code=java>File file = ... // Eine Datei String name = file.getName();</code=java> Hier wird die Methode "getName" eines File-Objektes aufgerufen.
Spezielle Typen
Nebst den "normalen Methoden" gibt es einige Methoden die sich etwas speziell verhalten.
statische Methoden
Statische Methoden, mit dem Modifier "static" markiert, gehören nicht zu einem Objekt, sondern zu einer Klasse. Diese Methoden haben deshalb keinen direkten Zugriff auf irgendwelche Variablen eines Objektes, da für sie schlicht kein Objekt existiert. Sie haben aber immernoch privilegierte Zugriffsrechte für alle Objekte, deren Typ der Klasse entspricht, in der die statische Methode definiert wurde.
Beispiel, folgendes funktioniert nicht: <code=java>public class Point{
private int x, y;
public static String asString(){ // FEHLER: x und y gehören zu einem Objekt, die // statische Methode hingegen zu einer Klasse return "X=" + x + ", Y=" + y; }
}</code=java>
Aber eine statische Methode kann sogar private Felder lesen: <code=java>public class Point{
private int x, y;
public static Point max( Point a, Point b ){ Point result = new Point(); // Zugriff auf die privaten Felder x und y: result.x = a.x > b.x ? a.x : b.x; result.y = a.y > b.y ? a.y : b.y;
return result; }
}</code=java>
Da statische Methoden zu Klassen gehören, müssen sie anders aufgerufen werden, als normale Methoden: <code=java>Point a = ... Point b = ...
// Aufruf einer normalen Methode: das Objekt wird angesprochen int x = a.getX();
// Aufruf einer statischen Methode: die Klasse wird angesprochen Point m = Point.max( a, b );</code=java>
abstrakte Methoden
Als abstrakte Methoden bezeichnet man Methoden, die keinen Rumpf besitzen (anstelle des Rumpfes wird ein Semikolon geschrieben). Abstrakte Methoden können nur in abstrakten Klassen oder Interfaces vorkommen. Sie müssen stets von einer erbenden Klasse Implementiert werden. <code=java>public abstract int operation( int a, int b );</code=java> Abstrakte Methoden können nicht statisch oder private sein, da sie sonst nicht überschreibbar wären.
finale Methoden
Finale Methoden lassen sich nicht überschreiben. Das kann theoretisch Geschwindigkeitsvorteile ergeben, macht aber die Verwendung der Klasse, in der die finale Methode ist, mühselig.
Das Schlüsselwort "final" wird verwendet, um eine finale Methode zu definieren:
<code=java>public final double min( double a, double b ){
if( a < b ) return a; else return b;
}</code=java>