JAVA / GETTING STARTED
Writing main and reading its signature
Write a correct main method, explain why each word in its signature is required, and read command-line arguments out of the String array you are handed.
What you will learn
- Write the signature the launcher matches: public static void main(String[] args)
- Explain why the entry point must be static, public and void
- Read command-line arguments from args and test args.length before indexing
- Spot which part of a broken signature caused 'Main method not found in class X'
Understanding Writing main and reading its signature
When you run java Signature, the launcher loads the class and then asks it for one very specific method: one named main that takes a single String array and returns nothing. The match is made on the method's name, its parameter types and its return type, so nothing you are free to rename has any effect on it. If no such method exists, not one line of your code runs, which is why you get a message from the launcher rather than a stack trace from inside your program.
static is required because no object of your class exists when the program starts; an instance method would force the launcher to guess which constructor to call and with what arguments. public is required because the call arrives from code outside your class and outside your package. void is there because no Java caller is waiting for a value, so an exit status comes from System.exit or defaults to 0 when main returns normally. String[] exists because the operating system hands a process a list of text tokens, and the launcher passes on the ones that follow the class name after it has consumed the JVM options.
Apart from that one lookup, main is an ordinary static method. You can call it from your own code, overload it, write the modifiers as static public, declare the parameter as String... or String args[], and name it args or argv, because a parameter name is invisible outside the method body. The array itself is a normal mutable array, empty rather than absent when nothing was passed, so args.length is the only honest way to ask whether the user supplied anything. Returning from main ends the work of the main thread, and the JVM shuts down once no other non-daemon threads are still running.
One extra habit pays off early: keep main short. Because it is the only method the launcher will call, it is tempting to pile the whole program into it, but everything inside main runs in a static context, so it cannot touch instance fields and quickly becomes hard to test. Treat main as a doorway that reads args and hands control to real methods or objects.
// run with: java Signature (no arguments)
public class Signature {
public static void main(String[] args) {
System.out.println("main entered with " + args.length + " argument(s)");
if (args.length == 0) {
main(new String[] { "alpha", "beta" });
System.out.println("the hand-written call returned");
} else {
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "] = " + args[i]);
}
}
}
}The main signature is an exact lookup key the java launcher matches before any object of your class exists, which is why every part of it is fixed.
Worked examples
The same signature, written differently
Shows which parts of the signature you may vary without the launcher losing track of main.
// run with: java Entry (no arguments)
public class Entry {
static public void main(String... argv) {
System.out.println("this class still starts");
System.out.println("argv type: " + argv.getClass().getSimpleName());
System.out.println("argv length: " + argv.length);
}
}Example explained
Line 1static public is accepted because the compiler does not care about the order of modifiers.
Line 2String... argv compiles to a String[] parameter, so the method the launcher looks up is unchanged.
Line 3argv.getClass().getSimpleName() prints String[], proving the varargs form is an array at runtime.
Line 4With no arguments the array is empty, not null, so argv.length is 0 and safe to read.
Overloading main
Demonstrates that the launcher chooses one exact signature and ignores every other method called main.
public class Overloads {
public static void main(String[] args) {
System.out.println("the launcher picked main(String[])");
main(7);
}
public static void main(int n) {
System.out.println("this overload runs only when code calls it: " + n);
}
}Example explained
Line 1Two methods named main can coexist because they differ in parameter type, which is ordinary overloading.
Line 2The launcher starts main(String[]) only; main(int) is invisible to it and would never start the program on its own.
Line 3main(7) is resolved by the compiler exactly like any other method call, which shows main has no special calling rules.
Line 4Control returns to main(String[]) after the overload finishes, and the program ends when that method returns.
Important notes
The array the launcher passes is never null, so if (args == null) is dead code; zero length is what 'no arguments' looks like. It can only be null if your own code calls main(null).
Java 25 finalised a relaxed launcher protocol in which a class may instead declare a non-private instance void main() with no parameters. The classic signature works on every Java version, so learn that one first.
Common mistakes
Writing main(String args) or spelling the method Main: the file compiles cleanly, then java stops with 'Main method not found in class X', because the launcher matches the exact name and parameter type rather than something close to it.
Assuming args[0] is the class or program name as in C: it is the first word after the class name, so every index is off by one, and reading args[0] when nothing was passed throws ArrayIndexOutOfBoundsException.
Declaring int main and returning 1 to report failure: the launcher will not accept that return type, so the class never starts; call System.exit(1) from a void main instead.
Try it yourself
Change, predict, then run
Write a class whose main prints args.length and, when args.length is 0, calls itself once with new String[] {"x", "y", "z"} and prints each element. Then change the parameter type from String[] to String, run it again, and note the exact message you get.
Open the Java workspaceCheck your understanding
A beginner wants main to be a normal instance method that the JVM calls on an object of the class. What is the real reason the entry point has to be static?
- When the program starts no object of the class exists, so the launcher needs a method it can invoke on the class itself
- Static methods are compiled to faster machine code, and the entry point must be fast
- Only static methods are allowed to declare an array parameter
- static is what makes the method reachable from outside its own package
Show answer
The class is loaded before any constructor has run, so a static method is the only thing the launcher can call without inventing constructor arguments. Option 4 confuses the two modifiers: reachability from outside the package comes from public, not static, and removing public breaks the call for a different reason.