0

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?

sevengold
  • 11
  • 2
  • 3
    This appears to be a typo in the book. The purpose is not to do static initialization of `OnDemandData` (like `static {...}` would do, but to define a `static` *inner class* named `Holder`. – Karl Knechtel Jan 01 '23 at 19:39
  • 3
    The author has even a [bugs page](https://horstmann.com/corejava/bugs.html#V2) for his book and this mistake is listed there together with the correction. – Thomas Kläger Jan 01 '23 at 20:45
  • @ThomasKläger Thanks. I checked that very page first! In fact, the author made yet another error by misattributing the bug under Volume II errors. This typo's **exclusive** to Volume I. – sevengold Jan 03 '23 at 13:35

1 Answers1

3

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.

knittl
  • 246,190
  • 53
  • 318
  • 364