Is a "named" static initializer valid Java?

50 Views Asked by At

I've only ever heard of a static initializers with the syntax "static {...}". But in this book, Core Java by Cay Horstmann, there's some code like this: (private static Holder {...})

12.4.13 On-Demand Initialization Sometimes, you have a data structure that you only want to initialize when it is first needed. And you want to ensure that initialization happens exactly once. Instead of designing your own mechanism, make use of the fact that the virtual machine executes a static initializer exactly once when the class is first used. The virtual machine ensures this with a lock, so you don’t have to program your own.

public class OnDemandData {
  // private constructor to ensure only one object is constructed
  private OnDemandData() {}
  public static OnDemandData getInstance() {
    return Holder.INSTANCE;
  }
  // only initialized on first use, i.e. in the first call to getInstance
  private static Holder {
    // VM guarantees that this happens at most once
    static final OnDemandData INSTANCE = new OnDemandData();
  }

}

That code does not compile. You'll get

/OnDemandData.java:12: error: <identifier> expected
  private static Holder {
                       ^
/OnDemandData.java:14: error: illegal start of expression
    static final OnDemandData INSTANCE = new OnDemandData();
    ^
/OnDemandData.java:17: error: class, interface, enum, or record expected
}
^
3 errors

So, what is it?

1

There are 1 best solutions below

0
knittl On

It's a typo and it is supposed to be a static nested class (private static class Holder):

public class OnDemandData {
  // private constructor to ensure only one object is constructed
  private OnDemandData() {}
  public static OnDemandData getInstance() {
    return Holder.INSTANCE;
  }
  // only initialized on first use, i.e. in the first call to getInstance
  private static class Holder {
    // VM guarantees that this happens at most once
    static final OnDemandData INSTANCE = new OnDemandData();
  }

}

See Java Singleton with an inner class - what guarantees thread safety? for an explanation of this technique.