In diesem Artikel erfährst du alles über die main-Methode in Java – dem Startpunkt eines jeden Java-Programms. Der Artikel beschreibt auch die Neuerungen von Java 21 bis 23, die sich derzeit noch im Preview-Stadium befinden.
Du erfährst im einzelnen:
- Was ist eine
main()
-Methode, und wofür brauchen wir sie? - Wie wird die
main()
-Methode aufgerufen? - Was sind die Bestandteile der
main()
-Methode in Java, und was bedeuten sie? - Wie kann man in neuen Java-Versionen die
main()
-Methode wesentlich einfacher schreiben?
Was ist eine main()-Methode in Java?
Damit ein Java-Programm gestartet werden kann, benötigt es eine main-Methode. Diese Methode ist der Einstiegspunkt in das Programm. Die JVM (Java Virtual Machine) ruft beim Start eines Programms diese main-Methode auf und führt den darin liegenden Java-Code aus.
Beispiel für eine main()-Methode in Java
Ein einfaches Hello-World-Java-Programm mit einer main-Methode sieht z. B. so aus:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Code-Sprache: Java (java)
Um dieses Programm zu starten, speichere den Programmcode zunächst in einer Datei mit dem Namen HelloWorld.java.
Gebe dann auf der Kommandozeile / in einem Terminal den folgenden Befehl ein:
java HelloWorld.java
Code-Sprache: Klartext (plaintext)
Du solltest nun folgende Ausgabe sehen:
Hello world!
Code-Sprache: Klartext (plaintext)
Glückwunsch! Du hast dein erstes Java-Programm geschrieben und gestartet.
Aber warum war das so kompliziert?
Was bedeuten all die Begriffe wie public
, class
, static
, void
, etc. im Programmcode?
Die gute Nachricht: Das musst du als Anfängerin / als Anfänger zunächst gar nicht wissen. Denn: In modernen Java-Versionen geht das viel einfacher!
Wie? Das wirst du im folgenden Abschnitt sehen.
(Falls es dich dennoch interessiert, findest du eine detaillierte Beschreibung aller Bestandteile der main-Methode weiter unten im Abschnitt Syntax der Java-main()-Methode.)
Die Java 21 main()-Methode
In Java 21 wurde die main-Methode stark vereinfacht. Diese Änderung befindet sich allerdings noch bis mindestens Java 23 im Preview-Stadium. Das bedeutet, dass sich Details noch ändern können und dass du die neue main-Methode noch nicht in Produktivcode einsetzen solltest.
In diesem Abschnitt zeige ich dir, was sich für dich ändert. Die technischen Details hinter diesen Änderungen erfährst du im Abschnitt Implicitly Declared Classes and Instance Main Methods.
Gehen wir noch einmal zurück zum Hello-World-Beispiel aus dem ersten Abschnitt:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Code-Sprache: Java (java)
Du musstest hier eine ganze Menge sogennanten „Boilerplate Code” schreiben – also Code, der in jedem Java-Programm immer wieder der gleiche wäre. Dabei ist das einzige, was du sagen willst: „Bitte gib den Text ‚Hello World!‘ aus.”
In Java 21 und der aktuellen Java-Version 22 (mit aktivierten Preview-Features) kannst du das bereits viel kürzer schreiben:
void main() {
System.out.println("Hello world!");
}
Code-Sprache: Java (java)
Und in der nächsten Java-Version 23 wird es noch einmal kürzer (ohne System.out
):
void main() {
println("Hello world!");
}
Code-Sprache: Java (java)
Die main-Methode und der Ausgabebefehl sind noch da – doch alles andere, einschließlich der Klasse um die main-Methode herum, wurde ersatzlos gestrichen.
Somit müssen sich Java-Anfängerinnen und -Anfänger in Zukunft keine Gedanken mehr über public
, class
, static
, etc. machen. Diese Begriffe können dann eingeführt werden, wenn sie wirklich gebraucht werden.
Beachte bitte, dass du Preview-Features explizit aktivieren musst. Wenn du beispielsweise die Java-22-Variante (das mittlere Beispiel) in einer Datei HelloWorld22.java speicherst, dann musst du das Programm wie folgt starten:
java --enable-preview --source 22 HelloWorld22.java
Code-Sprache: Klartext (plaintext)
Im folgenden Kapitel erfährst du, welche technischen Details hinter den Veränderungen stecken.
Implicitly Declared Classes and Instance Main Methods
Im vorherigen Abschnitt hast du erfahren, dass eine Java-main-Methode in Zukunft ohne Klasse, ohne public static
und ohne String[] args
geschrieben werden kann und dass für die Ausgabe statt System.out.println(
ein einfaches ...
)println(...)
genügt.
Damit ist der folgende Code in Zukunft ein gültiges und vollständiges Java-Programm:
void main() {
println("Hello world!");
}
Code-Sprache: Java (java)
Dieser Abschnitt beschreibt detailliert die Änderungen, die diese Vereinfachung ermöglicht haben.
Vorab die Historie der Änderungen:
- Alles begann in Java 21 mit einem Preview-Feature mit dem kompliziert klingenden Namen „Unnamed Classes and Instance Main Methods” (definiert in JDK Enhancement Proposal 445).
- In Java 22 wurde das Feature in die noch kompliziertere Bezeichnung „Implicitly Declared Classes and Instance Main Methods” umgenannt (definiert in JDK Enhancement Proposal 463).
- In Java 23 wurde das Feature noch einmal verbessert (JDK Enhancement Proposal 477).
Im Folgenden beschreibe ich die drei Bestandteile des neuen Features: implizit deklarierte Klassen, Instanz-main-Methoden und die automatisch importierte java.io.IO
-Klasse.
Implizit deklarierte Klassen
Für eine Java-Datei ohne explizite Klassendeklaration, also ohne beispielsweise public class HelloWorld
erzeugt der Java-Compiler in Zukunft eine sogenannte „implizite Klasse” mit einem vom Compiler festgelegten Namen. In der Regel ist das der Name der Datei ohne die .java-Endung.
Wenn du beispielsweise die Datei HelloWorld.java kompilierst, erzeugt der Compiler die Datei HelloWorld.class – und wenn du diese z. B. mit deiner IDE dekompilierst, siehst du, dass auch der Klassenname HelloWorld
ist.
Für implizite Klassen gelten die folgenden Besonderheiten:
- Eine implizite Klasse liegt immer im unbenannten Paket (so wie eine reguläre Klasse ohne
package
-Definition). - Eine implizite Klasse ist grundsätzlich
final
, von ihr kann also nicht geerbt werden. - Eine implizite Klasse kann keine Interfaces implementieren oder von anderen Klassen erben.
- Auf eine implizite Klasse kann nicht über den vom Compiler festgelegten Namen zugegriffen werden, d. h. andere Klassen können eine implizite Klasse nicht instanziieren, und keine Methoden darauf aufrufen, auch keine statischen.
Eine implizite Klasse kann jedoch Methoden auf sich selbst aufrufen, d. h. Methoden, die in derselben .java-Datei definiert sind, so wie in folgendem Beispiel:
void main() {
println(greeting());
}
String greeting() {
return "Hello, World!";
}
Code-Sprache: Java (java)
Da auf eine implizite Klasse von außerhalb nicht zugegriffen werden kann, muss sie immer eine main-Methode enthalten.
Instanz-main-Methoden
Instanz-main-Methoden sind nicht-statische main-Methoden, also main-Methoden ohne das static
-Keyword. Folgende main-Methoden sind zukünftig erlaubt:
- nicht statische Instanz-Methoden,
- Methoden mit dem Sichtbarkeitslevel public, protected oder package-private (ohne Modifier),
- Methoden mit oder ohne
String[]
-Parameter.
Hier sind ein paar Beispiele:
void main()
void main(String[] args)
public void main()
protected static void main(String[] args)
Statische und nicht-statische Methoden mit gleicher Signatur sowie Methoden mit unterschiedlichen Visibility-Modifiern bei gleicher Signatur schließen sich gegenseitig aus und führen zu einem „method is already defined”-Compiler-Fehler.
Es ist allerdings möglich, dass gleichzeitig eine main-Methode mit String[]
-Parameter und eine main-Methode ohne Parameter in derselben .java-Datei existieren:
void main(String[] args) {
. . .
}
protected static void main() {
. . .
}
Code-Sprache: Java (java)
Für diesen Fall wurde festgelegt, dass die Methode mit String[]
-Parameter Priorität hat, im Beispiel also void main(String[] args)
gestartet werden würde.
Konsoleninteraktion mit java.io.IO
Erst in der dritten Preview Phase der Änderungen, in Java 23, wurde die neue Klasse java.io.IO
eingeführt – mit folgenden statischen Methoden:
void print(Object obj)
– gibt den übergebenen Text oder die Text-Repräsentation des übergebenen Objekts auf der Konsole aus – ohne Zeilenumbruch am Ende.void println(Object obj)
– gibt den übergebenen Text oder die Text-Repräsentation des übergebenen Objekts auf der Konsole aus – mit Zeilenumbruch am Ende.String readln(String prompt)
– zeigt den übergebenen Prompt an, nimmt eine Benutzereingabe entgegen und gibt diese zurück.
Eine impliziert deklarierte Klasse importiert automatisch alle java.io.IO
-Methoden, so als würde die Klasse folgenden import-Anweisung enthalten:
import static java.io.IO.*;
Code-Sprache: Java (java)
Genau das macht es möglich, dass die Methoden ohne qualifizierenden Klassennamen-Präfix aufgerufen werden können.
Syntax der Java-main()-Methode
Dieser Abschnitt beschreibt die Syntax der main-Methode vor den in Java 21 eingeführten Vereinfachungen. Bisher musste eine main-Methode in eine Klasse eingebettet sein, und ihre Syntax war fest vorgegeben:
public class MyMainMethodDemo
public static void main(String[] args) {
// code to execute
}
// possibly more code
}
Code-Sprache: Java (java)
Nur der Name der Klasse, im Beispiel MyMainMethodDemo
, und der Name des Parameters, im Beispiel args
, dürfen frei gewählt werden.
Wenn ein Programm aus mehreren Klassen besteht, dürfen beliebig viele dieser Klassen eine main()
-Methode enthalten. Zum Start eines Programms wird, wie zu Beginn des Artikels gezeigt, der Name der Klasse angegeben, deren main()
-Methode gestartet werden soll.
Was bedeuten die einzelnen Elemente?
public class MyMainMethodDemo
Mit dieser ersten Codezeile wird eine Klasse im Sinne der objektorientierten Programmierung eingeleitet. MyMainMethodDemo
ist der Name der Klasse. Java-Code ist immer innerhalb von Klassen angeordnet.
public static void main(String[] args)
Mit der zweiten Zeile, der sogenannten Methodensignatur, wird eine Methode eingeleitet. Methoden enthalten den auszuführenden Programmcode.
public
public
ist ein sogenannter Sichtbarkeitsmodifikator. Eine Klasse sowie die darin enthaltene main()
-Methode müssen public
, also öffentlich sein, damit die JVM die main()
-Methode aufrufen und den darin enthaltenen Programmcode ausführen kann.
static
In der Objektorientierung wird zwischen statischen Methoden und Instanzmethoden unterschieden. Statische Methoden können aufgerufen werden, ohne dass eine Instanz der sie umgebenden Klasse – also ein Objekt – erzeugt werden muss. Instanzmethoden können hingegen nur auf einem Objekt aufgerufen werden.
Die main()
-Methode in Java muss statisch sein, um ohne Instanziierung der Klasse – also ohne Erzeugung eines Objekts dieser Klasse – aufrufbar zu sein.
void
Methoden können Werte zurückgeben, z. B. gibt die Methode Math.random()
eine Zufallszahl zurück. Eine main()
-Methode hat jedoch keinen Rückgabewert. Und genau das wird durch den Bezeichner void
angegeben.
String[] args
Hierbei handelt es sich um einen Parameter der Methode. String[]
ist der Typ des Parameters: ein String-Array. Und args
ist der Name des Parameters. Dieser Name darf geändert werden. Beim Start eines Programms können sogenannte Kommandozeilenparameter übergeben werden, z. B. so:
java HelloWorld.java happy coders out there
Code-Sprache: Klartext (plaintext)
Diese Parameter werden als String-Array an die main()
-Methode übergeben und können dort z. B. so ausgelesen und ausgegeben werden:
public class HelloWorld {
public static void main(String[] args) {
System.out.print("Hello");
for (String arg : args) {
System.out.print(" " + arg);
}
System.out.println("!");
}
}
Code-Sprache: Java (java)
Wenn du dieses Programm wie oben aufrufst, bekommst du folgende Ausgabe:
Hello happy coders out there!
Code-Sprache: Klartext (plaintext)
Fazit
Die main()
-Methode ist der Startpunkt eines jeden Java-Programms. Ohne diese kann kein Java-Programm starten. Bisher war die Syntax von main()
-Methoden starr vorgegeben:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Code-Sprache: Java (java)
In der aktuellen Java-Version 22 kann – mit aktivierten Preview-Features – dieselbe main()
-Methode wie folgt geschrieben werden:
void main() {
System.out.println("Hello world!");
}
Code-Sprache: Java (java)
Und in der kommenden Version, Java 23, geht es noch kürzer:
void main() {
println("Hello world!");
}
Code-Sprache: Java (java)
Das macht es inbesondere Java-Anfängerinnen und -Anfängern leichter, die Sprache zu erlernen. Konzepte, die erst für größere Programme relevant werden, wie Klassen, die Unterscheidung in statische und Instanzmethoden, Sichtbarkeitsmodifikatoren wie public
, protected
und private
sowie grobgranulare Strukturen wie Pakete und Module können so dann eingeführt werden, wenn sie gebraucht werden.
Wenn dir der Artikel gefallen hat, dann teile den Artikel über einen der Share-Buttons am Ende oder hinterlasse mir einen Kommentar.
Möchtest du informiert werden, wenn neue Artikel auf HappyCoders.eu veröffentlicht werden? Dann klicke hier, um dich für den HappyCoders.eu-Newsletter anzumelden.