Methode (Java)

Aus Byte-Welt Wiki
Version vom 28. Juni 2019, 07:50 Uhr von L-ectron-X (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springenZur Suche springen

In Java ist eine Methode eine sequenzielle Sammlung von ausführbaren Befehlen. Methoden implementieren das Verhalten einer Klasse. Dabei kapseln sie die Eigenschaften (Datenelemente) der Klasse.

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.

Syntax

Eine Methode besteht aus einem Kopf und einem Rumpf. Der Kopf stellt die Schnittstelle zur Außenwelt dar, der Rumpf hingegen ist der Code, der tatsächlich ausgeführt wird.

Kopf{
  Rumpf
}

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:

public static <X> X getRandom( List<X> list ) throws ListEmptyException;

Die Modifier sind hier "public static", es gibt ein Generic "X", die Rückgabe der Methode ist ein Objekt des Types "X", die Methode heißt "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 gesamten 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:

public void hide();

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:

public int max( int a, int b );

Eine Methode ohne Argumente:

public int max();

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:

public void writeFile( String path ) 
    throws NoSuchFileException, ReadOnlyFileException;

Methodenrumpf

Variablen

Innerhalb des Rumpfes kann man jederzeit neue Variablen definieren, und ihnen Werte zuweisen.

// neue Variablen
int x;
int y = 4;

// Zuweisung
x = y + 1;

Die Variablen sind außerhalb 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:

if( x < y ){
  z = x;
}
else{
  z = y;
}

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:

if( !file.exists() )
  throw new NoSuchFileException( file.getPath() );

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:

return x;

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:

return;

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:

int summe = plus( 23, 47 );

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:

File file = ... // Eine Datei
String name = file.getName();

Hier wird die Methode "getName" eines File-Objektes aufgerufen.

Spezielle Typen

Nebst den "normalen Methoden" gibt es einige Methoden die sich etwas speziell verhalten.

Konstruktormethode

Der Konstruktor_(Java) ist eine Sonderform der Methode.

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 immer noch privilegierte Zugriffsrechte für alle Objekte, deren Typ der Klasse entspricht, in der die statische Methode definiert wurde.

Beispiel, folgendes funktioniert nicht:

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;
  }
}

Aber eine statische Methode kann sogar private Felder lesen:

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;
  }
}

Da statische Methoden zu Klassen gehören, müssen sie anders aufgerufen werden, als normale Methoden:

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 );

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.

public abstract int operation( int a, int b );

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:

public final double min( double a, double b ){
  if( a < b )
    return a;
  else
    return b;
}

Weiterführendes Material