Java-Methoden

In den vorherigen Kapiteln haben wir oftSystem.out.println()verwendet, was ist es also?

  • println() ist eine Methode.
  • System ist eine Systemklasse.
  • out ist das Standardausgabeobjekt.

Diese Anweisung wird verwendet, um die Methode println() im Standardausgabeobjekt out der Systemklasse System aufzurufen.

Also, was ist eine Methode?

Eine Java-Methode ist eine Sammlung von Anweisungen, die gemeinsam eine Funktion ausführen.

  • Eine Methode ist eine geordnete Kombination von Schritten zur Lösung einer Klasse von Problemen.
  • Eine Methode ist in einer Klasse oder einem Objekt enthalten.
  • Eine Methode wird im Programm erstellt und an anderer Stelle referenziert.

Vorteile von Methoden

  • 1. Sie macht das Programm kürzer und klarer.
  • 2. Sie ist vorteilhaft für die Programmwartung.
  • 3. Sie kann die Effizienz der Programmentwicklung verbessern.
  • 4. Sie verbessert die Wiederverwendbarkeit von Code.

Regeln für die Benennung von Methoden

  • 1. Das erste Wort eines Methodennamens sollte mit einem Kleinbuchstaben beginnen, und nachfolgende Wörter sollten mit einem Großbuchstaben beginnen, ohne Trennzeichen zu verwenden. Zum Beispiel:addPerson。
  • 2. Unterstriche können in JUnit-Testmethodennamen vorkommen, um logische Komponenten des Namens zu trennen. Ein typisches Muster ist:test<MethodUnderTest>_<state>, zum BeispieltestPop_emptyStack。

Methodendefinition

Im Allgemeinen umfasst das Definieren einer Methode die folgende Syntax:

Modifizierer Rückgabewerttyp Methodenname(Parametertyp Parametername){... Methodenrumpf ...returnreturn value;}

Eine Methode besteht aus einem Methodenkopf und einem Methodenrumpf. Im Folgenden sind alle Teile einer Methode aufgeführt:

  • Modifizierer:Modifizierer sind optional und teilen dem Compiler mit, wie die Methode aufgerufen wird. Sie definieren den Zugriffstyp der Methode.
  • Rückgabewerttyp:Eine Methode kann einen Wert zurückgeben. returnValueType ist der Datentyp des von der Methode zurückgegebenen Werts. Einige Methoden führen die erforderliche Operation aus, geben aber keinen Wert zurück. In diesem Fall ist returnValueType das Schlüsselwortvoid。
  • Methodenname:Er ist der tatsächliche Name der Methode. Der Methodenname und die Parametertabelle bilden zusammen die Methodensignatur.
  • Parametertyp:Parameter wirken wie Platzhalter. Wenn eine Methode aufgerufen wird, wird ein Wert an den Parameter übergeben. Dieser Wert wird als aktuelles Argument oder Variable bezeichnet. Die Parameterliste bezieht sich auf die Parametertypen, die Reihenfolge und die Anzahl der Parameter. Parameter sind optional; eine Methode kann auch keine Parameter enthalten.
  • Methodenrumpf:Der Methodenrumpf enthält konkrete Anweisungen, die die Funktionalität der Methode definieren.

Zum Beispiel:

public static int age(int birthday){...}

Es kann mehrere Parameter geben:

static float interest(float principal, int year){...}

Hinweis:In einigen anderen Sprachen werden Methoden als Prozeduren und Funktionen bezeichnet. Eine Methode, die einen Nicht-void-Wert zurückgibt, wird als Funktion bezeichnet; eine Methode, die einen void-Wert zurückgibt, wird als Prozedur bezeichnet.

Beispiel

Die folgende Methode enthält 2 Parameter, num1 und num2, und sie gibt das Maximum dieser beiden Parameter zurück.

/** Gibt den größeren Wert zweier Integer-Variablen zurück*/ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; }

Eine kompaktere Schreibweise dafür (ternärer Operator):

public static int max(int num1, int num2) { return num1 > num2 ? num1 : num2; }

Methodenaufruf

Java unterstützt zwei Möglichkeiten, eine Methode aufzurufen, je nachdem, ob die Methode einen Wert zurückgibt.

Wenn ein Programm eine Methode aufruft, wird die Programmsteuerung an die aufgerufene Methode übergeben. Die Steuerung wird an das Programm zurückgegeben, wenn die aufgerufene Methode eine return-Anweisung ausführt oder die schließende geschweifte Klammer des Methodenrumpfs erreicht.

Wenn eine Methode einen Wert zurückgibt, wird der Methodenaufruf normalerweise als Wert behandelt. Zum Beispiel:

int larger = max(30, 40);

Wenn eine Methode void zurückgibt, muss der Methodenaufruf eine Anweisung sein. Zum Beispiel gibt die Methode println void zurück. Der folgende Aufruf ist eine Anweisung:

System.out.println("Willkommen bei Beispiel!");

Beispiel

Das folgende Beispiel zeigt, wie man eine Methode definiert und wie man sie aufruft:

TestMax.java Dateicode:

public class TestMax { /** Hauptmethode*/ public static void main(String[] args) { int i = 5; int j = 2; int k = max(i, j); System.out.println( i + "und" + j + "Vergleiche, der Maximalwert ist:" + k); } /** Gibt den größeren von zwei Integer-Variablen zurück*/ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; } }

Das obige Beispiel wird kompiliert und ausgeführt und liefert das folgende Ergebnis:

5 和 2 比较,最大值是:5

Dieses Programm enthält eine main-Methode und eine max-Methode. Die main-Methode wird von der JVM aufgerufen. Abgesehen davon unterscheidet sich die main-Methode nicht von anderen Methoden.

Der Header der main-Methode ist fest, wie im Beispiel gezeigt. Er hat die Modifizierer public und static, gibt einen void-Wert zurück, der Methodenname ist main, und er nimmt einen Parameter vom Typ String[] entgegen. String[] gibt an, dass der Parameter ein Array von Strings ist.


Das Schlüsselwort void

Dieser Abschnitt erklärt, wie man eine void-Methode deklariert und aufruft.

Das folgende Beispiel deklariert eine Methode namens printGrade und ruft sie auf, um die angegebene Punktzahl auszugeben.

Beispiel

Code der Datei TestVoidMethod.java:

public class TestVoidMethod { public static void main(String[] args) { printGrade(78.5); } public static void printGrade(double score) { if (score >= 90.0) { System.out.println('A'); } else if (score >= 80.0) { System.out.println('B'); } else if (score >= 70.0) { System.out.println('C'); } else if (score >= 60.0) { System.out.println('D'); } else { System.out.println('F'); } } }

Das obige Beispiel wird kompiliert und ausgeführt und liefert das folgende Ergebnis:

C

Hier ist die Methode printGrade eine Methode vom Typ void; sie gibt keinen Wert zurück.

Ein Aufruf einer void-Methode muss eine Anweisung sein. Daher wird sie in der dritten Zeile der main-Methode als Anweisung aufgerufen, genau wie jede Anweisung, die mit einem Semikolon endet.


Parameterübergabe als Wert

Beim Aufruf einer Methode müssen Sie Argumente angeben. Sie müssen sie in der Reihenfolge angeben, die in der Parameterliste festgelegt ist.

Zum Beispiel gibt die folgende Methode eine Nachricht n-mal hintereinander aus:

Code der Datei TestVoidMethod.java:

public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) { System.out.println(message); } }

Beispiel

Das folgende Beispiel veranschaulicht die Wirkung der Parameterübergabe als Wert.

Das Programm erstellt eine Methode, die zwei Variablen vertauscht.

Code der Datei TestPassByValue.java:

public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Vor dem Vertauschen ist der Wert von num1:" + num1 + ", und der Wert von num2 ist:" + num2); //Aufruf der swap-Methode swap(num1, num2); System.out.println("Nach dem Vertauschen ist der Wert von num1:" + num1 + ", und der Wert von num2 ist:" + num2); } /** Methode zum Vertauschen zweier Variablen*/ public static void swap(int n1, int n2) { System.out.println("\tEintritt in die swap-Methode"); System.out.println("\t\tVor dem Vertauschen ist der Wert von n1:" + n1 + ", der Wert von n2:" + n2); //Vertauschen der Werte von n1 und n2 int temp = n1; n1 = n2; n2 = temp; System.out.println("\t\tNach dem Tausch ist der Wert von n1" + n1 + ", der Wert von n2:" + n2); } }

Das obige Beispiel wird kompiliert und ausgeführt und liefert das folgende Ergebnis:

交换前 num1 的值为:1 ,num2 的值为:2
    进入 swap 方法
        交换前 n1 的值为:1,n2 的值:2
        交换后 n1 的值为 2,n2 的值:1
交换后 num1 的值为:1 ,num2 的值为:2

Übergeben Sie zwei Argumente, um die swap-Methode aufzurufen. Interessanterweise ändern sich die Werte der aktuellen Argumente nach dem Aufruf der Methode nicht.


Methodenüberladung

Die oben verwendete max-Methode funktioniert nur für Daten vom Typ int. Aber was, wenn Sie das Maximum zweier Daten vom Gleitkommatyp ermitteln möchten?

Die Lösung besteht darin, eine weitere Methode mit demselben Namen, aber unterschiedlichen Parametern zu erstellen, wie im folgenden Code gezeigt:

public static double max(double num1, double num2) { if (num1 > num2) return num1; else return num2; }

Wenn Sie beim Aufruf der max-Methode Parameter vom Typ int übergeben, wird die max-Methode mit int-Parametern aufgerufen;

Wenn Parameter vom Typ double übergeben werden, wird der Methodenrumpf der max-Methode mit double-Typ aufgerufen. Das nennt man Methodenüberladung;

Das heißt, zwei Methoden einer Klasse haben denselben Namen, aber unterschiedliche Parameterlisten.

Der Java-Compiler bestimmt anhand der Methodensignatur, welche Methode aufgerufen werden soll.

Das Überladen von Methoden kann Programme klarer und lesbarer machen. Methoden, die eng verwandte Aufgaben ausführen, sollten denselben Namen verwenden.

Überladene Methoden müssen unterschiedliche Parameterlisten haben. Sie können Methoden nicht allein aufgrund von Unterschieden in Modifikatoren oder Rückgabetypen überladen.


Gültigkeitsbereich von Variablen

Der Gültigkeitsbereich einer Variablen ist der Teil des Programms, in dem auf die Variable verwiesen werden kann.

In einer Methode definierte Variablen werden als lokale Variablen bezeichnet.

Der Gültigkeitsbereich einer lokalen Variablen beginnt bei ihrer Deklaration und reicht bis zum Ende des Blocks, der sie enthält.

Lokale Variablen müssen deklariert werden, bevor sie verwendet werden können.

Der Gültigkeitsbereich der Parameter einer Methode umfasst die gesamte Methode. Parameter sind eigentlich lokale Variablen.

In dem Initialisierungsteil einer for-Schleife deklarierte Variablen haben einen Gültigkeitsbereich, der die gesamte Schleife umfasst.

Variablen, die im Schleifenkörper deklariert werden, haben jedoch einen Gültigkeitsbereich von ihrer Deklaration bis zum Ende des Schleifenkörpers. Er enthält Variablendeklarationen, wie unten gezeigt:

Sie können eine lokale Variable mit demselben Namen mehrmals in verschiedenen, nicht verschachtelten Blöcken einer Methode deklarieren, aber Sie können eine lokale Variable nicht zweimal in verschachtelten Blöcken deklarieren.

Verwenden von Kommandozeilenargumenten

Manchmal möchten Sie beim Ausführen eines Programms Nachrichten an ein Programm übergeben. Dies wird erreicht, indem Kommandozeilenargumente an die main()-Funktion übergeben werden.

Kommandozeilenargumente sind die Informationen, die auf den Programmnamen folgen, wenn das Programm ausgeführt wird.

Beispiel

Das folgende Programm gibt alle Kommandozeilenargumente aus:

Code der Datei CommandLine.java:

public class CommandLine { public static void main(String[] args){ for(int i=0; i<args.length; i++){ System.out.println("args[" + i + "]: " + args[i]); } } }

Führen Sie dieses Programm wie folgt aus:

$ javac CommandLine.java 
$ java CommandLine this is a command line 200 -100
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

Konstruktormethoden

Ein Konstruktor ist eine spezielle Methode, die verwendet wird, um Objekte einer Klasse zu erstellen. Wenn ein Objekt mit dem Schlüsselwort new erstellt wird, wird der Konstruktor automatisch aufgerufen, um die Eigenschaften des Objekts zu initialisieren.

Eigenschaften von Konstruktoren:

  • Der Methodenname ist derselbe wie der Klassenname: Der Name des Konstruktors muss mit dem Klassennamen übereinstimmen.
  • Kein Rückgabetyp: Konstruktoren haben keinen Rückgabetyp; sogarvoidvoid kann nicht geschrieben werden.
  • Wird beim Erstellen eines Objekts automatisch aufgerufen: Jedes Mal, wenn Sienewnew zum Erstellen eines Objekts verwenden, wird der Konstruktor automatisch aufgerufen.
  • Können überladen werden: Sie können mehrere Konstruktoren für dieselbe Klasse definieren, aber die Parameterlisten dieser Konstruktoren müssen unterschiedlich sein (d. h., sie stellen eine Überladung dar).

Unabhängig davon, ob Sie einen benutzerdefinierten Konstruktor definieren, haben alle Klassen Konstruktoren, weil Java automatisch einen Standardkonstruktor bereitstellt. Der Zugriffsmodifizierer des Standardkonstruktors ist derselbe wie der der Klasse (wenn die Klasse public ist, ist der Konstruktor ebenfalls public; wenn die Klasse in protected geändert wird, wird der Konstruktor ebenfalls in protected geändert).

Sobald Sie Ihren eigenen Konstruktor definieren, wird der Standardkonstruktor ungültig.

Beispiel

Das Folgende ist ein Beispiel für die Verwendung eines Konstruktors:

//Ein einfacher Konstruktor class MyClass { int x; //Das Folgende ist der Konstruktor MyClass(int i ) { x = i; } }

Sie können den Konstruktor wie folgt aufrufen, um ein Objekt zu initialisieren:

Code der Datei ConsDemo.java:

public class ConsDemo { public static void main(String[] args) { MyClass t1 = new MyClass( 10 ); MyClass t2 = new MyClass( 20 ); System.out.println(t1.x + " " + t2.x); } }

Das Ausführungsergebnis ist wie folgt:

10 20

Weitere Informationen finden Sie im nächsten Kapitel:Java-Konstruktoren。

Variable Argumente

Seit JDK 1.5 unterstützt Java das Übergeben variabler Argumente desselben Typs an eine Methode.

Die Deklaration der variablen Argumente einer Methode sieht wie folgt aus:

typeName... parameterName

In der Methodendeklaration fügen Sie nach dem angegebenen Parametertyp einen Auslassungspunkt (...) hinzu.

Eine Methode kann nur ein variables Argument angeben, und es muss der letzte Parameter der Methode sein. Alle gewöhnlichen Parameter müssen davor deklariert werden.

Beispiel

Code der Datei VarargsDemo.java:

public class VarargsDemo { public static void main(String[] args) { //Aufruf einer Methode mit variablen Argumenten printMax(34, 3, 3, 2, 56.5); printMax(new double[]{1, 2, 3}); } public static void printMax( double... numbers) { if (numbers.length == 0) { System.out.println("Kein Argument übergeben"); return; } double result = numbers[0]; for (int i = 1; i < numbers.length; i++){ if (numbers[i] > result) { result = numbers[i]; } } System.out.println("Der Maximalwert ist " + result); } }

Das obige Beispiel wird kompiliert und ausgeführt und liefert das folgende Ergebnis:

The max value is 56.5
The max value is 3.0

Die finalize()-Methode

Die finalize-Methode ist in Java 9 als veraltet markiert und wird in künftigen Java-Versionen entfernt. Es wird empfohlen, try-with-resourcestry-with-resources zu verwendenoderjava.lang.ref.Cleanerum Ressourcen zu verwalten.

Java ermöglicht es, eine solche Methode zu definieren, die aufgerufen wird, bevor ein Objekt durch den Garbage Collector zerstört (eingesammelt) wird. Diese Methode heißt finalize() und wird verwendet, um das Objekt, das gerade eingesammelt wird, aufzuräumen.

Beispielsweise können Sie finalize() verwenden, um sicherzustellen, dass eine von einem Objekt geöffnete Datei geschlossen wird.

In der finalize()-Methode müssen Sie die Operationen angeben, die ausgeführt werden sollen, wenn das Objekt zerstört wird.

Das allgemeine Format von finalize() ist:

protected void finalize() { //Der Beendigungscode steht hier. }

Das Schlüsselwort protected ist ein Qualifizierer, der sicherstellt, dass die finalize()-Methode nicht von Code außerhalb der Klasse aufgerufen wird.

Natürlich kann die Speicherbereinigung von Java automatisch durch die JVM erfolgen. Wenn Sie sie manuell verwenden möchten, können Sie die oben genannte Methode verwenden.

Beispiel

Code der Datei FinalizationDemo.java:

public class FinalizationDemo { public static void main(String[] args) { Cake c1 = new Cake(1); Cake c2 = new Cake(2); Cake c3 = new Cake(3); c2 = c3 = null; System.gc(); //Aufruf des Java-Garbage-Collectors } } class Cake extends Object { private int id; public Cake(int id) { this.id = id; System.out.println("Cake-Objekt " + id + "wird erstellt"); } protected void finalize() throws java.lang.Throwable { super.finalize(); System.out.println("Cake-Objekt " + id + "wird entsorgt"); } }

Wenn Sie den obigen Code ausführen, lautet das Ausgabeergebnis wie folgt:

$ javac FinalizationDemo.java 
$ java FinalizationDemo
Cake Object 1is created
Cake Object 2is created
Cake Object 3is created
Cake Object 3is disposed
Cake Object 2is disposed

Alternative:Es wird empfohlen, das AutoCloseable-Interface in Kombination mit einer try-with-resources-Anweisung zu verwenden, um Ressourcen automatisch zu schließen. Zum Beispiel:

try (Resource res = new Resource()) {
    // 使用资源
} catch (Exception e) {
    e.printStackTrace();
}
Andere Erweiterungen