Java - Using Unnamed Classes and Instance Methods Examples

This tutorial shows you how to define unnamed classes and instance main methods in Java.

Java developers are already familiar with the public static void main(String args[]) method, which is the entry point of a program that can be launched. The method itself is usually put inside a named class. In Java 21, there is a new concept that allows us to define unnamed classes and instance main methods. For a better understanding, you can read this tutorial.

Using Instance Main Methods

Before Java 21, a class that can be executable as an entry point is required to have a main method written as public static void main(String args[]).

  public class MyClass {
  
    public static void main(String[] args) {
      System.out.println("Hello, World!");
    }
  }

Java 21 introduced a new way to define the main method by using instance main methods. The difference of such methods is that you don't need to write the access modifier, static keyword, and String[] parameter.

  public class MyClass {
  
    void main() {
      System.out.println("Hello, World!");
    }
  }

The String[] argument can still be passed though if it's necessary.

  public class MyClass {
  
    void main(String[] arg) {
      System.out.println("Hello, World!");
    }
  }

There are several new concepts that you need to understand. Before Java 21, the main method must have a public access modifier. Now, the main method can have any access modifier as long as it's not private. Therefore, you can use public, protected, or default (package protected). However, it's not allowed to use private.

Basically, it's possible to define more than one main method as long as the method signatures are different. Below are the rules you need to know.

  • If the class has two main methods, Java will choose the one with static over the non-static.
  • If the class doesn't have any static main method but has a non-static one, there must be a parameter with zero parameter. Java will construct an instance of the class and call the non-static main method.
  • If the main methods are both static or non-static, the one with the String[] parameter is chosen over the one without the parameter.

In the example below, the upper one will be invoked because it's static and the other is non-static.

  public class MyClass {

    public MyClass() {
      System.out.println("Constructor");
    }
  
    void static main() {
      System.out.println("Hello, World 1!");
    }
  
    public void main(String[] args) {
      System.out.println("Hello, World 2!");
    }
  }

Output:

  Hello, World 1!

If both main methods are static, the one with the parameter is preferred.

  public class MyClass {

    public MyClass() {
      System.out.println("Constructor");
    }

    static void main() {
      System.out.println("Hello, World 1!");
    }
  
    public static void main(String[] args) {
      System.out.println("Hello, World 2!");
    }
  }

Output:

  Hello, World 2!

Below is another example without any static main method. The lower one will be invoked because they're both non-static and the one with the parameter is preferred. If the invoked main method is not static, Java will call the constructor of the class which has zero parameter. By default, the zero parameter constructor is created by Java if you do not explicitly define any constructor in the class.

  public class MyClass {

    public MyClass() {
      System.out.println("Constructor");
    }
  
    void main() {
      System.out.println("Hello, World 1!");
    }
  
    public void main(String[] args) {
      System.out.println("Hello, World 2!");
    }
  }

Output:

  Constructor
  Hello, World 2!

If you define another constructor with one or more parameters without defining the one with zero parameter, you'll get the exception below.

  error: can't find no argument constructor in class: com.woolha.example.MyClass

Using Unnamed Classes

Java 21 also allows you to define a class without a name. Traditionally, a Java class must be given a name in the declaration. It's no longer mandatory since Java 21, which makes it possible to create a class without a name. It's intended to be the entry point of a program and must have a main method in the form of void main() or void main(String[] args). Therefore, it's not suitable if you have to refer to it from another class or file.

There are several important things that you need to know.

  • An unnamed class is always a member of the unnamed package. Even if the file is put under the directory of a package, it's not allowed to write the package name at the top of the file. If you add the package name like in the following code.
  package com.woolha.example;
  
  void main() {
    System.out.println("Hello, World!");
  }

The compiler will give you the following error.

MyScript.java:1: error: unnamed class should not have package declaration
    package com.woolha.example;
    ^
    Note: MyScript.java uses preview features of Java SE 21.
    Note: Recompile with -Xlint:preview for details.
    1 error
    error: compilation failed
  • It cannot be referenced by name. As a result it's not possible to directly construct an instance of an unnamed class. With that limitation, it's only suitable to be an entry point that can be run.
  • It's always final. Therefore, another class cannot extend it, added with the fact that it cannot be referenced by name.
  • It cannot implement any interface or extend any class other than Object. Java doesn't allow and doesn't provide a syntax that makes it possible to do that.
  • It's possible to have multiple unnamed classes in the same project. Each unnamed class represents a program with a main method.
  • You cannot create a custom constructor with an unnamed class. Just like a named class, there will be a default constructor with zero parameters. The difference is you are not allowed to define another constructor.

Summary

Java 21 allows more flexibility for creating the entry point of a program. First, the public modifier and static keyword of the main method are no longer required, as does the String[] argument. In addition, you don't have to create a named class. Creating a Java file with a void main method is enough to make it executable.

To use this feature the minimum Java version is 21. If it's still a preview feature in the Java version that you use, you have to add --enable-preview flag when running the code.

You can also read about: