main, and the arguments it is handed

Why the signature is exactly that, what the JVM passes you, and what the shell did to it first.

4 min read🔧 Setting Up Java
java
public static void main(String[] args)

Every word of that is required, and each one is required for a reason. Getting one wrong produces a program that compiles perfectly and will not start.

Why each word

public — the JVM has to call it from outside your class. Anything narrower and it cannot.

static — it is called before any object exists. The JVM has your class and nothing else; there is no instance for it to call a method on, so the method must belong to the class itself.

void — nothing meaningful could receive a return value. (The process's exit code comes from System.exit or from finishing normally, not from main.)

main — the name the JVM looks for. Not configurable.

String[] args — what you were invoked with. The type and the fact that it is an array are fixed; the name is not, and String... args works too because varargs is an array underneath.

Change any of the first four and you get this:

plaintext
Error: Main method not found in class Greet, please define the main method as:
   public static void main(String[] args)

Which is an unusually helpful error, because it prints the thing you needed.

What the JVM hands you

java
public class Greet {
    public static void main(String[] args) {
        System.out.println("args.length = " + args.length);
        for (int i = 0; i < args.length; i++)
            System.out.println("  args[" + i + "] = " + args[i]);
    }
}
plaintext
$ java Greet
args.length = 0
 
$ java Greet hello world "two words"
args.length = 3
  args[0] = hello
  args[1] = world
  args[2] = two words

Three things worth noticing, because each is a place people are wrong:

The array is empty, never null. java Greet with no arguments gives you a zero-length array. args == null is a check you do not need and will never fire.

The program name is not in it. In C, argv[0] is the program. In Java, args[0] is the first argument. There is no slot for the class name.

The shell split them, not Java. "two words" arrived as one argument because the shell removed the quotes and passed a single string. Java received three strings and has no idea quotes were involved. This is why a path with a space in it breaks a script that forgot to quote a variable — the splitting already happened before your code ran.

What arguments are, and are not, for

They are fine for a small program, a script, a one-off tool.

For a service, configuration goes in the environment rather than in arguments, for the reasons the foundations course gives: the same artifact runs everywhere and only its environment differs. You will see Spring Boot accept both — --server.port=8081 as an argument and SERVER_PORT=8081 as a variable — and the environment is the one that survives a container.

And secrets never go in arguments. Anything on a command line is visible to ps for anyone on the machine.

More than one main

Any class can have a main. That is not a mistake — it is how a project ends up with several entry points, and how people put a quick test harness inside a class.

Which one runs is decided entirely by what you name on the command line:

bash
java com.shop.Order       # runs Order's main
java com.shop.Report      # runs Report's main

A jar can declare a default in its manifest, which is what lets java -jar app.jar work without naming a class. That is the build tool's business, and the next lesson touches where things live.

Try it yourself

Find out what arrives

Write the program above, then:

  1. Run it with no arguments. Is args null or empty?
  2. Pass three words. Pass one quoted phrase. What is the difference in args.length?
  3. Pass --name=Alice. How many arguments, and what is in them?
  4. Rename main to Main and run it. What exactly does the error say?
  5. Remove static and run it. Same error, or different?
What you learn
  1. Empty, length 0. Never null.
  2. Three words → 3. One quoted phrase → 1. The shell decided, before Java saw anything.
  3. One argument, the literal string --name=Alice. No parsing happened.
  4. and 5. The same error both times — "Main method not found… please define the main method as: public static void main(String[] args)". The JVM is looking for a method matching that exact signature; a wrong name and a missing static both mean it is not there, and it cannot tell you which you got wrong. That is why the message just prints the correct form.
Progress is saved on this device and to your account when signed in.