java main methodjava main method
HappyCoders Glasses

Java main()
Method Syntax and Simplification Since Java 25

Sven Woltmann
Sven Woltmann
Last update: June 11, 2026

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.

Since Java 25, the code runs directly with java HelloWorld.java.

Only in the preview versions Java 21 through 24 did you have to enable the feature explicitly – for example, with java --enable-preview --source 24 HelloWorld.java.

In the following section, you'll learn the technical details behind these changes.

Compact Source Files and Instance Main Methods

In Java 24, this feature was called “Simple Source Files and Instance Main Methods,” and before that “Implicitly Declared Classes 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 package declaration).
  • 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.

In Java 23 and Java 24, this class still resided in the java.io package, and an implicitly declared class imported its methods automatically – so you could call println() without a qualifying class name prefix.

In Java 25, the IO class was moved to the java.lang package, and the automatic import of the IO methods was removed again. This means that since Java 25, you either write IO.println() – or you import the println() method statically:

import static java.lang.IO.*;

With this import declaration, you can call println() and the other IO methods without a class name prefix in Java 25 as well.

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

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.

With Compact Source Files and Instance Main Methods, this is no longer required.

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.

With Compact Source Files and Instance Main Methods, this is no longer required.

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.

With Compact Source Files and Instance Main Methods, this is no longer required.

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.