Java 25 finalizes JEP 512: Compact Source Files and Instance Main Methods, a game-changing feature that dramatically reduces boilerplate code for simple programs. With this update, Java finally offers a beginner-friendly way to write code without the overhead of explicit classes, public static void main
, or import statements—making the language more accessible than ever.
Whether you’re a student learning your first “Hello, World!” or an experienced developer writing quick prototypes, Java 25 streamlines the experience.
Why This Matters: Java Without the Boilerplate
Traditionally, every Java program needed:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
For decades, this was a rite of passage—but also a barrier. Beginners had to learn about classes, static methods, arrays, String, System.out, packages, imports, main keyword meaning and public access modifiers before they could even print text.
With JEP 512, that barrier disappears. You can now write:
void main() {
IO.println("Hello, World!");
}
That’s it—no class, no public static
, no imports. Behind the scenes, the compiler creates an implicit class, instantiates it, and runs your main
.
The Evolution of Instance Main Methods and Compact Source Files
Java 21 – The First Step (JEP 445)
- Instance main methods introduced: You no longer need
public static void main(String[] args)
. Instead, you can declarevoid main()
orvoid main(String[] args)
as an instance method inside a class. - Unnamed classes: Programs could omit the class declaration entirely; the compiler would wrap top-level methods into an unnamed class.
Example:
void main() {
System.out.println("Hello, World!");
}
Java Launcher behavior in Java 21:
When you run java HelloWorld.java
, the launcher uses this decision process:
- Check for
public static void main(String[] args)
→ if present, run it (classic behavior). - If not found, but there is a
static void main()
with no parameters → run that. - If still not found but the class has:
- a non-private, zero-argument constructor (default, package-private, protected, or public), and
- a non-private instance
main
method →
then the launcher creates an instance of the class and runs the appropriate method:- If an instance
main(String[] args)
exists → run it. - Otherwise, run the no-arg
main()
.
- If an instance
Java 22 – Cleaner Entry Points (JEP 463)
What Changed?
Renamed and Simplified Class Behavior
Java 21’s “unnamed classes” concept was replaced in Java 22 with a more streamlined and intuitive model: implicitly declared classes, or implicit classes. Instead of requiring a special classification, the compiler now treats any top-level code without an explicit class
declaration as belonging to a standard class automatically generated by the compiler. This class is given a host-determined name (the name of your .java file), is final
, belongs to the unnamed package, extends Object
, and cannot implement interfaces—yet functions like a regular class in behavior.
Why the change?
The term “unnamed class” was misleading and technically complex. By contrast, “implicit class” is simpler: it’s just sugar for a normal class that the compiler inserts on your behalf. The new approach dropped the special unnamed concept, favoring a cleaner design where implicit classes are indistinguishable from ordinary ones, except they can’t be referenced by name or subclassed.
Java Launcher behavior in Java 22:
When you run java HelloWorld.java
, the launcher uses this decision process, If there is a candidate main
method with a String[]
parameter then we invoke that method; otherwise we invoke a candidate main
method with no parameters. There is no ambiguity here because a class cannot declare a static method and an instance method of the same name and signature.
Java 23 – Built-In Imports and I/O (JEP 477)
In Java 23, the Java team made things even simpler: no need to reference System.out
and wonder what it means. They introduced a new IO
class with print/read features (print
, println
, readln
), and the amazing part is that these methods are auto-imported, so you can directly write println("Hello, World!");
. In addition, all public classes in java.base
are now auto-imported, making types like List
, File
, or BigDecimal
usable with zero ceremony.
Example:
void main() {
println("Hello, World!");
}
OR
void main() {
var authors = List.of("Alice", "Bob");
println(authors.get(0));
}
Java 24 – Simple Source Files (JEP 495)
Unified the feature under the name simple source files instead of Implicit classes, but nothing has been changed in the code feature!
Java 25 – Finalized Features (JEP 512)
With Java 25, compact source (using compact source files instead of simple source files from java 24) files and instance main methods are standard, permanent features.
- The static methods originally provided in
java.io.IO
(println
, …) have been moved tojava.lang.IO
(and since everything injava.lang
is imported by default, they are now more accessible).
IO Class methods:
public static void print(Object obj);
public static void println(Object obj);
public static void println();
public static String readln(String prompt);
public static String readln();
- These operations are now based on
System.out
/System
.in rather than the Console API. However, the static methods of theIO
class are no longer implicitly imported into compact source files. This means that method calls must explicitly reference the class, e.g.:
IO.println("Hello, world!");
unless the methods are explicitly imported (ie, import static java.lang.IO.println😉
Examples
Printing Output
void main() {
IO.println("Hello, World!");
}
Reading Input
void main() {
String name = IO.readln("Enter your name: ");
IO.println("Nice to meet you, " + name);
}
Using Collections Without Imports
Compact source files automatically access all public classes and interfaces from java.base
module (ie, import module java.base;)
void main() {
var authors = List.of("Alice", "Bob");
IO.println(authors.get(0));
}
Conclusion: A New Era of “Programming in the Small”
JEP 512 marks a turning point. With compact source files and instance main methods, Java finally aligns with beginner expectations while preserving its scalability for enterprise use.
From Java 21’s preview to Java 25’s final release, this evolution shows a clear vision: making Java simpler for small programs, powerful for big ones.
Now, a new developer can start with:
void main() {
IO.println("Hello, World!");
}
—and later grow into the full richness of Java’s class-based, modular ecosystem.
Java 25 is not just an update—it’s a reboot of the Java learning experience.
👉 Looking for more details? Explore the official JEP 512 page and JDK 25 release notes.