04.03.05 Sonderfall main

Bisher haben wir immer die noch nicht näher beschriebene Methode main verwendet. Diese Methode ist der Einstiegspunkt für alle Java Programme. Hier startet das Programm mit seinen Anweisungen.

Sonderfall main

Die Main-Methode wird immer als erstes ausgeführt – einmal abgesehen von Initialisierungen zum VM Start und möglichen statischen Initialisierern innerhalb der Startklasse. Der Methodenkopf ist strikt vorgegeben und darf nicht geändert werden, da sonst die VM diesen Einstiegspunkt nicht findet. Sind alle Anweisungen innerhalb dieser Methode abgearbeitet endet das Programm ebenfalls mit der main Methode.

Der Aufbau sieht folgendermaßen aus.

public static void main(String[] args) {}

Es handelt sich hierbei um eine öffentliche Klassenmethode (siehe Kapitel 04.03.06 Sichtbarkeitsmodifizierer und Kapitel 04.03.07 Verwendung von static).
Die Main-Methode ist so wichtig, dass es nicht ausreicht nur die Methodensignatur, bestehend aus Methodenname und Parameterliste, einzuhalten, sondern der komplette Methodenkopf muss übereinstimmen. Wie erinnern uns aus Kapitel 04.03.03 Methoden daran, dass der Rückgabetyp nicht mit zur Methodensignatur gehört. Um zu überprüfen, ob die VM wirklich den kompletten Methodenkopf überprüft und nicht nur die Signatur, um die Main-Methode zu finden, testen wir dies mit einem kleinen Beispiel. Wir wollen unsere main mit einem Rückgabetyp versehen.

public static int main(String[] args) {
  return 1;
}

Dies würde sich ohne Probleme kompilieren aber nicht ausführen lassen. Wir erhalten folgende Fehlermeldung.

Fatale VM Exception

Auf der Konsole erscheint ebenfalls eine Meldung.

java.lang.NoSuchMethodError: main
Exception in thread "main"

Sie sehen also wie wichtig es ist diese Methode korrekt zu definieren.

Dennoch kann die Main-Methode geringfügig angepasst werden. Es ist bspw. seit JDK >=1.5 möglich, den letzten Parameter einer Methode als sogenannte Varargs anzugeben.

public static void main(String... args) {}

Das ist allerdings nur eine andere Schreibweise und wird intern wieder auf ein String Array abgebildet (siehe auch Kapitel 06.07 Autoboxing bzw. Varargs bei Sun).

Eine weitere Variante, komplett ohne Main-Methode, führt ebenfalls zu einer ausführbaren Anwendung.

public class Test {

  static {

    System.out.println("Ich laufe ohne main.");
    System.exit(0);
  }
}

Dies funktioniert mit Hilfe statischer Initialisierer (siehe Kapitel 04.03.09 Statische Initialisierer). Man muss hierbei jedoch selbstständig für ein (korrektes) Beenden der Anwendung sorgen. Dies geschieht mit System.exit(int status), welches am Ende des Kapitels noch einmal näher erläutert wird.

Auch zulässig ist das Weiterleiten von Ausnahmen (Exceptions) mit dem Schlüsselwort throws.

public static void main(String[] args) throws InterruptedException {
		
  Thread.sleep(1000);
}

Dies erspart uns selbst die Behandlung der Ausnahme. Weiteres hierzu entnehmen Sie bitte Kapitel 05.02 Fehlerbehandlung.

Und zu guter Letzt darf die Main-Methode um die Modifizierer strictfp, final und synchronized ergänzt werden.

Der Parameter args

Wie Sie vielleicht festgestellt haben, enthält die main einen Parameter args.

Da diese Methode ja „automatisch“ aufgerufen wird, ergibt sich die berechtigte Frage, was dieses String Array für Daten enthält und wo diese herkommen.
Die in diesem Array enthaltenen Werte sind jene, welche beim Programmstart als sogenannte Konsolenparameter mit übergeben wurden. Sie kennen so etwas vielleicht aus dem UNIX Terminal bzw. DOS Konsolen Umfeld.

telnet 192.168.1.99
net TIME

Die Werte 192.168.1.99 sowie TIME sind die Parameter für das aufgerufene Programm/Befehl.

Für Java wollen wir dies an einem Beispiel einmal näher betrachten.

public class ParameterTest {

  public static void main(String[] args) {

    if (args.length == 2) {
      System.out.println("Parameter 1: " + args[0]);
      System.out.println("Parameter 2: " + args[1]);
    } 
    else {
      System.out.println("Bitte geben Sie zwei Parameter ein!");
      System.out.println("ParameterTest Para1 Para2");
    }
  }
}

In dieser Main-Methode verwenden wir den Parameter args. Zuerst überprüfen wir, ob dem Programm beim Start zwei Parameter mitgegeben wurden. Ist dies der Fall werden diese ausgegeben, ansonsten erhält der Anwender eine Ausgabe, dass zwei Parameter gefordert werden. Wie Sie mit dem Parameter args genau arbeiten, entnehmen Sie bitte dem Kapitel 02.09 Arrays, da es sich um ein normales Array, bestehend aus String Objekten, handelt.
Um unserer Programm zu verwenden gehen wir wie folgt vor.

Zu erst kompilieren wir den Quellcode.

javac ParameterTest.java

Nun können wir unser Programm ausführen und diesem zeitgleich die Parameter mit auf den Weg geben.

java ParameterTest Becks Radeberger

Dies führt zu folgender Ausgabe.

Parameter 1: Becks
Parameter 2: Radeberger

Die einzelnen Parameter werden bei der Übergabe durch Leerzeichen voneinander getrennt. Jeder so übergebene Parameter ist dann ein Element des Stringarrays args.

Übergeben wir zum Programmstart keine zwei Parameter erscheint unser Hinweis.

java ParameterTest nurEinParameter

Bitte geben Sie zwei Parameter ein!
ParameterTest Para1 Para2

Zusammenfassung

Die Main-Methode ist als Einstiegspunkt eines Java Programms die wichtigste Methode. Ohne sie läuft nichts. Innerhalb der Startklasse muss diese Methode definiert werden, da wir sonst einen Laufzeitfehler erhalten. Ihr kompletter Methodenkopf muss unverändert übernommen werden, damit sie auch gefunden wird. Innerhalb dieser Methode kann man auf die zum Programmstart übergebenen Konsolenparameter zugreifen. Auf diese kann man mit Hilfe des String[] Parameters zugreifen. Nach Abarbeitung der letzten Anweisung innerhalb der main endet auch das Java Programm selbst. Es gibt allerdings auch die Möglichkeit eine Anwendung explizit zu beenden. Diese Funktionalität wird durch die Klassenmethode exit(int status) der Klasse System bereitgestellt. Für obiges Beispiel lässt sich dies folgendermaßen verwenden.

public class ParameterTest {

  public static void main(String[] args) {

    if (args.length == 2) {
      System.out.println("Parameter 1: " + args[0]);
      System.out.println("Parameter 2: " + args[1]);
    } 
    else {
      System.out.println("Bitte geben Sie zwei Parameter ein!");
      System.out.println("ParameterTest Para1 Para2");


      System.exit(1);
    }
  }
}

Der Parameter, welcher der Methode exit(int status) übergeben wird, dient als Indikator über die Art der Beendigung. Wird die Anwendung normal beendet, sollte hier immer "0" verwendet werden. Ansonsten eine höhere Zahl, die idealerweise noch etwas über die Art des Fehlers aussagt.

5 Replies to “04.03.05 Sonderfall main”

  1. Illuvatar

    Mit
    public static void main (String… args)
    geht es übrigens auch 😉

    Wobei ich mich da grade frage – gibt es varargs zur Laufzeit eigentlich überhaupt noch?

  2. Sebastian Würkner

    Hiho,

    ja seit JDK 1.5 funktioniert es auch mit String… args.
    Ein Blick auf den decompilierten Bytecode verrät aber was intern abläuft.

    Source:
    public static void main (String… args)

    JAD Decompiled:
    public static transient void main(String args[])

    javap Disassembler:

    Constant pool:
    const #5 = String #27; // Parameter 1:
    ...
    const #9 = String #32; // Parameter 2:

    Signatur:
    public static void main(java.lang.String[]);
    Signature: ([Ljava/lang/String;)V

    Programmstart:
    0: aload_0
    1: arraylength
    2: iconst_2

    Verwendung:
    13: invokespecial #4; //Method java/lang/StringBuilder."":()V
    16: ldc #5; //String Parameter 1:
    ...
    40: invokespecial #4; //Method java/lang/StringBuilder."
    ":()V
    43: ldc #9; //String Parameter 2:

    Also wie gehabt! 😉
    Es wird einfach auf ein Array gemappt wie vermutet.

    Zusätzlich sollte man bei Java varargs noch bedenken, dass nur der letzte Parameter so übergeben werden darf.

    public void machWas(String... att1, int i)

    Das geht nicht.

    bye Saxony

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.