4

So I was going through the Math.java source code and I found that there is a holder class created to hold the randomNumberGenerator static variable. Here is the relevant piece of code.

public final class Math {
 // other methods.
 public static double random() {
   return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
 }

 private static final class RandomNumberGeneratorHolder {
   static final Random randomNumberGenerator = new Random();
 }
}

IMO, We could have simply declared the randomNumberGenerator as private static final inside the Math class itself.

My question is, Is there any advantage of creating a separate holder class for this? Or it is just a personal preference.

Hardik Modha
  • 12,098
  • 3
  • 36
  • 40

4 Answers4

10

This is an example of the initialisation-on-demand holder pattern. When the Math class is loaded by the JVM, the Random instance will not be constructed immediately. Instead that will only happen when the random() method is called, at which point the RandomNumberGenreatorHolder class will be loaded, and the Random singleton object constructed.

Essentially the code is ensuring that the Random singleton is created lazily.

Richard Fearn
  • 25,073
  • 7
  • 56
  • 55
4

They are both lazy, but one is lazier (singleton pattern that is). Having a private static field would mean that when the class holding that field is initialized, that field is initialized also. So if you need to call a method on that class, but you don't need that singleton, it will still get initialized.

On the other hand, having a nested class will prevent that, and it will be initialized when actually used.

To be exact, this is very rarely a case where this would matter and the jdk-itself is most probably one of the very very few examples.

Eugene
  • 117,005
  • 15
  • 201
  • 306
3

This is an example of a lazy-initialized singleton that is implemented using nested classes.

The "holder" gets initialized the first time that random() is called. The first call triggers the execution of the static initialization of the RandomNumberGeneratorHolder class.

(It is worthwhile doing this lazily. Initializing a random generator without supplying a seed entails going to the OS to get some "entropy" to seed the generator. That is a relatively expensive operation. You don't want the JVM incurring that cost that if random() is not going to be called.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

As mentioned in the answer of this post, the purpose of the holder pattern is to get a single instance created for that class, invocation on demand (lazy loading) and also being thread-safe. It is the best option when you want to develop the Singleton pattern.

batero
  • 143
  • 2
  • 10