W3docs

The Java main Method

What public static void main(String[] args) means, why each modifier is required, and how command-line arguments are passed.

Every Java application begins life inside a method with a very specific signature: public static void main(String[] args). The JVM looks for that signature, calls it once, and your program runs until that call returns (or the program is otherwise stopped). Get any part of the signature wrong and the JVM refuses to start the program.

You've been writing this line on every example so far. This chapter pulls it apart so you know what each word is doing and what flexibility you have.

The signature, word by word

public static void main(String[] args) { ... }
  • public — the JVM is "outside" your class. To call main from the outside, it has to be public. Any tighter visibility (private, package-private) and the JVM can't reach it.
  • static — the JVM doesn't construct an instance of your class first; it calls main on the class itself. So main must belong to the class, which is what static means.
  • voidmain returns nothing. The exit code of a Java program isn't a return value; it's set with System.exit(...) or defaults to 0 on a clean finish.
  • main — the literal name the JVM looks for. Spell it Main, mian, or anything else and the JVM throws NoSuchMethodError: main.
  • String[] args — a single parameter, an array of strings, holding the command-line arguments. Parameter name doesn't matter (args, argv, cmdline), only the type.

The parameter array may also be written as varargs — String... args — which is the same type to the JVM and behaves identically:

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

Both forms work. Most code uses String[] args out of convention.

Command-line arguments

When you run a Java program from the terminal, anything after the class name becomes elements of the args array:

$ java Greet Ada Lovelace

Inside Greet.main, args is {"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.length is the number of arguments — 0 if none were supplied.
  • Each element is always a String. To use a numeric argument as a number, parse it: int n = Integer.parseInt(args[0]);.
  • Quotes group spaces in the shell — java Foo "hello world" puts one element "hello world" in args.

What's not allowed

The signature is fixed; small deviations don't work:

  • void main(String[] args) — missing public static. Won't start.
  • public void main(String[] args) — missing static. Won't start.
  • public static int main(String[] args)int return type. Won't start.
  • public static void main(String args) — wrong parameter type. Won't start.
  • public static void Main(String[] args) — capital M. Won't start.

What is allowed and harmless:

  • final on the parameter or the method: public static final void main(final String[] args).
  • Throws clauses: public static void main(String[] args) throws Exception. Sometimes convenient for quick experiments.
  • Vararg form: public static void main(String... args).

Multiple classes, one main

Each public top-level class can have its own main. When you run java SomeClass, the JVM looks in that class for main. So a large project can have dozens of classes that all carry a main for testing or for separate entry points; only the one you name on the command line is the entry point of that run.

// 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 runs the first; java Sum 1 2 3 runs the second and prints 6.

Exiting a Java program

main returning normally ends the program with exit code 0. To exit early, or to set a non-zero exit code (signaling an error to whoever ran the program), use System.exit:

if (args.length == 0) {
  System.err.println("usage: Sum <number>...");
  System.exit(1);
}

System.exit doesn't return — it stops the JVM. Use it sparingly; in libraries it's almost never the right tool. In a small command-line program it's the standard way to signal "I couldn't do my job."

A worked example

java— editable, runs on the server

What's next

That closes the methods part: you can write methods, pass parameters, overload them, recurse, vary the argument count, and host the entry point that drives the whole program. The next part introduces the bigger container methods live inside — classes and objects — and the first taste of Java's object-oriented model.

Practice

Practice

Which change to public static void main(String[] args) prevents the JVM from running the program?