Why must the Java main method be declared public static void main with a String array parameter, and what fails if you get one of those wrong?
The JVM launcher is not calling your method by name from inside your code — it reflects on the class you name and looks for a method with a very specific shape. All four parts are load-bearing.
public is required because the launcher code lives in a different package than your class, and the reflective lookup it performs uses the same access rules as ordinary method invocation. static is required because the launcher must invoke the method before any instance of your class exists. There is no object to call it on, so the method has to belong to the class itself. void is required because the launcher has no use for a return value; the process exit status is decided separately. And the parameter must be an array of String, because that is the channel the launcher uses to hand you the command-line arguments. The array wrapper exists because the number of arguments is not known in advance.
Remove any one of them and the launcher reports that it cannot find the main method in your class, even though a method with a similar name is plainly present. The classic mistake is dropping static: the method compiles perfectly, unit tests happily call it, and only the launcher complains at run time. You can confirm the exact shape the launcher needs by inspecting the class reflectively.
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Main {
public static void main(String[] args) throws Exception {
Method m = Main.class.getDeclaredMethod("main", String[].class);
System.out.println("signature : " + m);
System.out.println("is public : " + Modifier.isPublic(m.getModifiers()));
System.out.println("is static : " + Modifier.isStatic(m.getModifiers()));
System.out.println("returns void : " + (m.getReturnType() == void.class));
System.out.println("param type : " + m.getParameterTypes()[0].getSimpleName());
}
}One related detail: the launcher looks up the method by name and parameter types, not by return type, so a class may legally contain public static void main(String[] args) alongside another method also called main with a different signature. The extra method is simply not an entry point.