Die Java-Methode main
Was public static void main(String[] args) bedeutet, warum jeder Modifier erforderlich ist und wie Kommandozeilenargumente übergeben werden.
Jede Java-Anwendung beginnt in einer Methode mit einer ganz bestimmten Signatur: public static void main(String[] args). Die JVM sucht nach dieser Signatur, ruft sie einmal auf, und das Programm läuft, bis dieser Aufruf zurückkehrt (oder das Programm anderweitig beendet wird). Stimmt auch nur ein Teil der Signatur nicht, verweigert die JVM den Programmstart.
Diese Zeile schreiben Sie seit Hello World in jedem Beispiel. Dieses Kapitel zerlegt sie, damit Sie verstehen, was jedes Wort bewirkt und welchen Spielraum Sie haben.
Die Signatur, Wort für Wort
public static void main(String[] args) { ... }public— die JVM befindet sich „außerhalb" Ihrer Klasse. Ummainvon außen aufzurufen, muss sie public sein. Bei einer engeren Sichtbarkeit (private, package-private) kann die JVM sie nicht erreichen.static— die JVM erzeugt zuerst keine Instanz Ihrer Klasse; sie ruftmaindirekt auf der Klasse auf. Daher mussmainzur Klasse gehören, wasstaticbedeutet.void—maingibt nichts zurück. Der Exit-Code eines Java-Programms ist kein Rückgabewert; er wird mitSystem.exit(...)gesetzt oder ist standardmäßig0bei einem sauberen Beenden.main— der wörtliche Name, nach dem die JVM sucht. Schreiben SieMain,mianoder irgendetwas anderes, schlägt der JVM-Start mitError: Main method not found in class ...fehl.String[] args— ein einzelner Parameter, ein Array von Strings, der die Kommandozeilenargumente enthält. Der Parametername spielt keine Rolle (args,argv,cmdline), nur der Typ.
Das Parameter-Array kann auch als Varargs geschrieben werden — String... args — was für die JVM denselben Typ darstellt und sich identisch verhält:
public static void main(String... args) { ... }Beide Formen funktionieren. Die meisten Code-Beispiele verwenden aus Konvention String[] args.
Kommandozeilenargumente
Wenn Sie ein Java-Programm vom Terminal aus ausführen, wird alles nach dem Klassennamen zu Elementen des args-Arrays:
$ java Greet Ada LovelaceInnerhalb von Greet.main ist args gleich {"Ada", "Lovelace"}:
public class Greet {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Hello, stranger");
} else {
System.out.println("Hello, " + String.join(" ", args));
}
}
}args.lengthist die Anzahl der Argumente —0, wenn keine angegeben wurden.- Jedes Element ist immer ein
String. Um ein numerisches Argument als Zahl zu verwenden, parsen Sie es:int n = Integer.parseInt(args[0]);. - Anführungszeichen gruppieren Leerzeichen in der Shell —
java Foo "hello world"fügt ein einzelnes Element"hello world"inargsein.
Was nicht erlaubt ist
Die Signatur ist festgelegt; kleine Abweichungen lassen sich zwar kompilieren, schlagen aber beim Start fehl — die JVM gibt eine Error:-Meldung aus und beendet sich, bevor irgendetwas von Ihrem Code ausgeführt wird:
public void main(String[] args)— fehlendesstatic.Error: Main method is not static in class ....void main(String[] args)— fehlendespublic static. Gleicher Fehler „not static".public static int main(String[] args)— Rückgabetypint.Error: Main method must return a value of type void in class ....public static void Main(String[] args)— großesModer ein anderer Name.Error: Main method not found in class ....public static void main(String args)— falscher Parametertyp (ein einzelnerString, kein Array).Error: Main method not found in class ....
Beachten Sie, dass es sich um Laufzeitfehler handelt, nicht um Kompilierfehler — javac akzeptiert sie alle problemlos. Die Überprüfung findet statt, wenn java versucht, einen Einstiegspunkt zu finden.
Was erlaubt ist und keinen Schaden anrichtet:
finalbeim Parameter oder der Methode:public static final void main(final String[] args).- Throws-Klauseln:
public static void main(String[] args) throws Exception. Manchmal praktisch für schnelle Experimente. - Vararg-Form:
public static void main(String... args).
Mehrere Klassen, eine main
Jede öffentliche Top-Level-Klasse kann ihre eigene main-Methode haben. Wenn Sie java SomeClass ausführen, sucht die JVM in dieser Klasse nach main. Ein großes Projekt kann also Dutzende von Klassen haben, die alle eine main-Methode für Tests oder separate Einstiegspunkte tragen; nur diejenige, die Sie in der Kommandozeile angeben, ist der Einstiegspunkt dieses Laufs.
// File Greet.java
public class Greet {
public static void main(String[] args) { System.out.println("greet"); }
}
// File Sum.java
public class Sum {
public static void main(String[] args) {
int total = 0;
for (String s : args) total += Integer.parseInt(s);
System.out.println(total);
}
}java Greet führt die erste aus; java Sum 1 2 3 führt die zweite aus und gibt 6 aus.
Ein Java-Programm beenden
Wenn main normal zurückkehrt, endet das Programm mit Exit-Code 0. Um vorzeitig zu beenden oder einen Exit-Code ungleich null zu setzen (als Signal für einen Fehler an den Aufrufer), verwenden Sie System.exit:
if (args.length == 0) {
System.err.println("usage: Sum <number>...");
System.exit(1);
}System.exit kehrt nicht zurück — es stoppt die JVM. Verwenden Sie es sparsam; in Bibliotheken ist es fast nie das richtige Mittel. In einem kleinen Kommandozeilenprogramm ist es die Standardmethode, um zu signalisieren: „Ich konnte meine Aufgabe nicht erfüllen."
Ein vollständiges Beispiel
Was kommt als Nächstes
Damit ist der Methodenteil abgeschlossen: Sie können Methoden schreiben, Parameter übergeben, sie überladen, rekursiv aufrufen, die Argumentanzahl variieren und den Einstiegspunkt bereitstellen, der das gesamte Programm steuert. Der nächste Teil stellt den größeren Container vor, in dem Methoden leben — Klassen und Objekte — und gibt einen ersten Einblick in Javas objektorientiertes Modell.