Static method reference in an anonymous class

Consider the following contrived “hello, world”:

abstract public class Main implements java.util.function.Supplier<Runnable> {
    public static void main(String[] args) {
        new Main() {
            private void hello() {
                System.out.println("hello, world");
            }
            @Override
            public Runnable get() {
                return this::hello;
            }
        }.get().run();
    }
}

This works. Now, imagine I realize that the hello method can be made static, how do I now get the reference to that method? Static method reference require to use the name of the class, which by definition is not there. I tried just trying to refer to hello or ::hello or null::hello but these are not acceptable for the compiler.

Since the method is static, this can of course be easily worked around by putting the static method in the Main class and referring to it as Main::hello, but in a more complex setup the advantage of being able to refer to the static method would be restricting the static method to the smallest possible context. A case can be made of course that probably at that point you are probably abusing the ability to have anonymous classes, but my question mostly comes from curiosity to understand whether referring to static methods of anonymous classes is possible at all.

In Java, when you define an anonymous class, you can have both instance methods and static methods. However, the static methods are bound to the class they are defined in, not the anonymous class itself. This means you cannot directly reference a static method defined in an anonymous class because anonymous classes do not have a name.

Why You Can’t Reference Static Methods Directly in Anonymous Classes

  1. Anonymous Class Context: An anonymous class does not have a name, so you cannot refer to its static methods using the syntax of ClassName::methodName. The only way to access a static method is through its declaring class.
  2. Access Scope: Static methods belong to the class level and are not tied to the instance of an anonymous class. When you define a static method inside an anonymous class, it still belongs to that anonymous class’s enclosing class, but it’s not accessible in a way that lets you use the class name directly.

Example of How to Achieve Your Goal

If you want to use a static method in a similar context while keeping it scoped tightly, you can use a few different approaches. Here are a couple of possible solutions:

1. Define the Static Method in a Named Class

Instead of using an anonymous class, define a named static inner class that can have static methods.

public class Main {
    public static void main(String[] args) {
        new Inner().get().run();
    }

    static class Inner implements java.util.function.Supplier<Runnable> {
        private static void hello() {
            System.out.println("hello, world");
        }
        @Override
        public Runnable get() {
            return Inner::hello; // Reference to the static method
        }
    }
}

2. Use a Static Method in the Outer Class

If you want to keep the static method within a limited scope but still need to call it from an anonymous class, you can define it in the enclosing class:

public class Main {
    public static void main(String[] args) {
        new RunnableSupplier().get().run();
    }

    private static void hello() {
        System.out.println("hello, world");
    }

    static class RunnableSupplier implements java.util.function.Supplier<Runnable> {
        @Override
        public Runnable get() {
            return Main::hello; // Reference to the static method in the outer class
        }
    }
}

3. Using Lambda Expressions

If the method is static, you can also simply use a lambda expression instead of an anonymous class:

public class Main {
    public static void main(String[] args) {
        Runnable runnable = (Runnable) Main::hello; // Reference to the static method
        runnable.run();
    }

    private static void hello() {
        System.out.println("hello, world");
    }
}

Conclusion

In summary, you cannot directly reference static methods of anonymous classes in Java because they lack a name. To utilize static methods while restricting their visibility, you can either define them in a named inner class or the outer class. This approach maintains the benefits of scoping while allowing method references.