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 callmainfrom 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 callsmainon the class itself. Somainmust belong to the class, which is whatstaticmeans.void—mainreturns nothing. The exit code of a Java program isn't a return value; it's set withSystem.exit(...)or defaults to0on a clean finish.main— the literal name the JVM looks for. Spell itMain,mian, or anything else and the JVM throwsNoSuchMethodError: 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 LovelaceInside 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.lengthis the number of arguments —0if 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"inargs.
What's not allowed
The signature is fixed; small deviations don't work:
void main(String[] args)— missingpublic static. Won't start.public void main(String[] args)— missingstatic. Won't start.public static int main(String[] args)—intreturn type. Won't start.public static void main(String args)— wrong parameter type. Won't start.public static void Main(String[] args)— capitalM. Won't start.
What is allowed and harmless:
finalon 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
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
Which change to public static void main(String[] args) prevents the JVM from running the program?