

In this article, you'll learn all about the main() method in Java – the entry point of every Java program. The article also covers the simplifications finalized in Java 25.
In detail, you'll learn:
- What is a
main()method, and why do we need it? - How is the
main()method invoked? - What are the components of the
main()method in Java, and what do they mean? - How can you write the
main()method far more easily in modern Java versions?
What Is the main() Method in Java?
To start a Java program, it needs a main() method. This method is the program's entry point. When a program starts, the JVM (Java Virtual Machine) calls this main() method and executes the Java code it contains.
Example of a main() Method in Java
A simple Hello World Java program with a main() method looks like this, for example:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}Code language: Java (java)To run this program, first save the code in a file named HelloWorld.java.
Then enter the following command on the command line / in a terminal:
java HelloWorld.javaCode language: plaintext (plaintext)You should now see the following output:
Hello world!Code language: plaintext (plaintext)Congratulations! You've written and run your first Java program.
But why was that so complicated?
What do all those terms like public, class, static, void, and so on mean in the code?
The good news: as a beginner, you don't need to know any of that at first. Because in modern Java versions, it's much simpler!
How? You'll see in the next section.
(If you're curious anyway, you'll find a detailed description of all the components of the main() method further down, in the section Syntax of the Java main() Method.)
The Simplified main() Method
In Java 25, the main() method was greatly simplified (the simplifications were available as a preview feature from Java 21 through Java 24).
In this section, I'll show you what changes for you. You'll learn the technical details behind these changes in the section Compact Source Files and Instance Main Methods.
Let's go back to the Hello World example from the first section:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}Code language: Java (java)Here you had to write a whole lot of so-called “boilerplate code” – code that would be the same in every Java program. Yet the only thing you actually want to say is: “Please print the text ‘Hello World!’.”
Since Java 25 (and in Java 21 through 24 with preview features enabled), you can write this much more concisely:
void main() {
IO.println("Hello world!");
}Code language: Java (java)The main() method and the println output command are still there – but a lot of the surrounding boilerplate has been removed, and System.out.println() has been shortened to IO.println().
This means Java beginners no longer have to worry about public, class, static, and so on. These concepts can be introduced once they're actually needed.
In the following section, you'll learn the technical details behind these changes.
Compact Source Files and Instance Main Methods
In the previous section, you learned that a Java main() method can be written without a class, without public static, and without String[] args, and that for output, the shorter IO.println(…) is enough instead of System.out.println(…).
This makes the following code a valid and complete Java program:
void main() {
IO.println("Hello world!");
}Code language: Java (java)This section describes in detail the changes that made this simplification possible.
Below, I'll describe the five components of the feature: compact source files, implicitly declared classes, instance main methods, the new java.lang.IO class for console output, and the automatic import of the java.base module.
Compact Source Files
A Java file without an explicit class declaration – that is, without something like public class HelloWorld – is called a “compact source file.”
Implicitly Declared Classes
From the code in a compact source file, the Java compiler generates a so-called “implicitly declared class” with a name determined by the compiler. In practice, that's the file name without the .java extension.
If you compile the file HelloWorld.java, for example, the compiler produces the file HelloWorld.class – and if you decompile it, say with your IDE, you'll see that the class name is HelloWorld as well.
However, you must not rely on this name: it's implementation-specific and can change.
The following special rules apply to implicit classes:
- An implicitly declared class always resides in the unnamed package (just like a regular class without a
packagedeclaration). - An implicitly declared class is always
final, so it cannot be subclassed. - An implicitly declared class cannot implement interfaces or extend other classes.
- An implicitly declared class cannot be accessed through the name assigned by the compiler – that is, other classes cannot instantiate it or call any of its methods, not even static ones.
An implicitly declared class can, however, call methods on itself – that is, methods defined in the same .java file, as in the following example:
void main() {
IO.println(greeting());
}
String greeting() {
return "Hello, World!";
}Code language: Java (java)Since an implicitly declared class cannot be accessed from the outside, it must always contain a main() method.
Instance Main Methods
Instance main methods are non-static main() methods – that is, main() methods without the static keyword. The following main() methods are allowed:
- non-static instance methods,
- methods with the visibility level
public,protected, or package-private (no modifier), - methods with or without a
String[]parameter.
Here are a few examples:
void main()void main(String[] args)public void main()protected static void main(String[] args)
Static and non-static methods with the same signature, as well as methods with different visibility modifiers but the same signature, are mutually exclusive and lead to a method is already defined compiler error.
It is possible, however, for a main() method with a String[] parameter and a main() method without parameters to exist in the same .java file at the same time:
void main(String[] args) {
// . . .
}
protected static void main() {
// . . .
}Code language: Java (java)For this case, it has been specified that the method with the String[] parameter takes priority – in the example, void main(String[] args) would be started.
The reason is backward compatibility: even before the simplifications, a class could contain – alongside the classic entry method public static void main(String[] args) – an additional, overloaded main() method without parameters. However, only the variant with the String[] parameter ever served as the entry point. This exact behavior is preserved so that existing programs start unchanged.
Console Interaction with java.lang.IO
The new IO class was introduced in the third preview phase of these changes, in Java 23. Since the finalization in Java 25, it provides five static methods:
void print(Object obj)– prints the given text, or the text representation of the given object, to the console – without a trailing line break.void println(Object obj)– prints the given text, or the text representation of the given object, to the console – with a trailing line break.void println()– prints just a line break, i.e., an empty line.String readln(String prompt)– displays the given prompt, reads user input, and returns it.String readln()– reads user input without displaying a prompt first, and returns it.
Automatic Import of the java.base Module
Many standard classes are useful even in small programs. So that you don't have to write an import for them every time, a compact source file automatically imports the entire java.base module – as if the declaration import module java.base; appeared at the top of the file.
This lets you use classes from commonly used packages such as java.util, java.io, or java.math without an explicit import:
void main() {
var names = List.of("Anna", "Ben", "Carla");
for (var name : names) {
IO.println(name);
}
}Code language: Java (java)List is immediately available here, even though there's no import java.util.List; in the code.
As soon as your program grows and you move it into a regular class, this automatic import no longer applies. You then add the necessary imports yourself – for example, with a module import declaration import module java.base; at the top of the file. To learn exactly how these module import declarations work, see import modules in Java: Module Import Declarations.
The History of the Changes
- It all started in Java 21 with a preview feature bearing the complicated-sounding name “Unnamed Classes and Instance Main Methods” (defined in JDK Enhancement Proposal 445).
- In Java 22, the feature was renamed to the even more complicated label “Implicitly Declared Classes and Instance Main Methods” (defined in JDK Enhancement Proposal 463).
- In Java 23, the feature was improved once more (JDK Enhancement Proposal 477).
- In Java 24, the feature was renamed to “Simple Source Files and Instance Main Methods” but remained in the preview stage (JDK Enhancement Proposal 495).
- In Java 25, the feature was finalized under the name “Compact Source Files and Instance Main Methods” (JDK Enhancement Proposal 512).
Syntax of the Java main() Method
This section describes the classic syntax of the main() method as it was before the simplifications – and as it still applies in larger programs. Classically, a main() method is embedded in a class, and its syntax is fixed:
public class MyMainMethodDemo {
public static void main(String[] args) {
// code to execute
}
// possibly more code
}Code language: Java (java)Only the class name – MyMainMethodDemo in the example – and the parameter name – args in the example – may be chosen freely.
If a program consists of several classes, any number of them may contain a main() method. To start a program, you specify – as shown at the beginning of the article – the name of the class whose main() method should be started.
What do the individual elements mean?
public class MyMainMethodDemo
This first line of code introduces a class in the sense of object-oriented programming. MyMainMethodDemo is the name of the class. Java code is always organized within classes.
public static void main(String[] args)
The second line, the so-called method signature, introduces a method. Methods contain the code to be executed.
public
public is a so-called visibility modifier. A class and the main() method it contains must be public so that the JVM can call the main() method and execute the code it contains.
static
Object orientation distinguishes between static methods and instance methods. Static methods can be called without creating an instance of the surrounding class – that is, an object. Instance methods, on the other hand, can only be called on an object.
The main() method in Java must be static so that it can be called without instantiating the class – that is, without creating an object of this class.
void
Methods can return values – for example, the Math.random() method returns a random number. A main() method, however, has no return value. And that is exactly what the void keyword indicates.
String[] args
This is a parameter of the method. String[] is the parameter's type: a String array. And args is the parameter's name. This name may be changed. When a program is started, so-called command-line arguments can be passed, for example, like this:
java HelloWorld.java happy coders out thereCode language: plaintext (plaintext)These arguments are passed to the main() method as a String array and can be read and printed there, for example, like this:
public class HelloWorld {
public static void main(String[] args) {
System.out.print("Hello");
for (String arg : args) {
System.out.print(" " + arg);
}
System.out.println("!");
}
}Code language: Java (java)If you run this program as shown above, you get the following output:
Hello happy coders out there!Code language: plaintext (plaintext)Conclusion
The main() method is the entry point of every Java program. Without it, no Java program can start. Classically, the syntax of a main() method is rigidly prescribed:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}Code language: Java (java)Since Java 25 (and in Java 21 through 24 with preview features enabled), you can write the same main() method as follows:
void main() {
IO.println("Hello world!");
}Code language: Java (java)This makes it easier – especially for Java beginners – to learn the language. Concepts that only become relevant for larger programs – such as classes, the distinction between static and instance methods, visibility modifiers like public, protected, and private, as well as higher-level structures like packages and modules – can then be introduced once they're needed.