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 since Hello World. 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 fails to launch with Error: Main method not found in class ....
  • 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 varargsString... 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 compile fine but fail at launch — the JVM prints an Error: and exits before any of your code runs:

  • public void main(String[] args) — missing static. Error: Main method is not static in class ....
  • void main(String[] args) — missing public static. Same "not static" failure.
  • public static int main(String[] args)int return type. Error: Main method must return a value of type void in class ....
  • public static void Main(String[] args) — capital M, or any other name. Error: Main method not found in class ....
  • public static void main(String args) — wrong parameter type (a single String, not an array). Error: Main method not found in class ....

Notice these are launch-time errors, not compile errors — javac is happy with all of them. The check happens when java tries to find an entry point.

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?
Which change to public static void main(String[] args) prevents the JVM from running the program?
Was this page helpful?