Initialize static variables of Interface via Enum

I am trying to understand the below behavior, all I am trying is to initialize the static variable of interface via enum method.

enum Hello {
    ProfileResolver();

    public Hello resolve() {
        System.out.println("resolve method called!!!!");
        return ProfileResolver;
    }
}
public interface Resolver{
  Hello hello = Hello.ProfileResolver.resolve(); // this should called when creating an instace of any implementation
}

Implentation class like below

public class Impl implements Resolver{
}

and now if

public static void main(String[] arg){
   Resolver resolver = new Impl();
}

Now at this point I was expecting just before object initialization of Impl object, hello variable of Interface must initialize and resolve method called, but it is not. And when I declare Resolver as class instead of inteface, it is working as expected. Can anyone help me try to understand ?

Answer

Here are the specified triggers for static initialization of types in Java. This is from the Java Language Specification

12.4.1. When Initialization Occurs
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • A static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

When a class is initialized, its superclasses are initialized (if they have not been previously initialized), as well as any superinterfaces (§8.1.5) that declare any default methods (§9.4.3) (if they have not been previously initialized). Initialization of an interface does not, of itself, cause initialization of any of its superinterfaces.

A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization.

A class or interface will not be initialized under any other circumstance.

A careful analysis indicates that your code does not meet any of the requirements for the Resolver interface’s static initialization to be carried out…

  • new Impl() causes the initialization of Impl, but this does not cause the intialization of Resolver, because Resolver does not have any default methods (see my bold-italic text emphasis).

  • Nothing requires that a reference to the Resolver type should trigger initialization

  • The way to cause this code to trigger Resolver‘s initialization is to either add a default method to it (no point in this), or to read its static variables:

    public static void main(String[] args) throws Exception {
        Resolver resolver = new Impl();
        System.out.println(Resolver.hello); //causes initialization
    }
    

If you’re using Hello hello = Hello.ProfileResolver.resolve(); to trigger some intended side-effects through the resolve() method, then please don’t.