Correct implementation of initialization-on-demand holder idiom

前端 未结 3 989
轮回少年
轮回少年 2020-12-10 12:36

I have got two versions of \"Initialization-on-demand holder idiom\":

  1. http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
  2. http://en.wik
相关标签:
3条回答
  • 2020-12-10 13:21
    private static class LazyHolder {
        $VISIBILITY static final Singleton INSTANCE = new Singleton();
    

    From a consumer's point of view it does not really matter if $VISIBILITY is public or private because the LazyHolder type is private. The variable is only accessible via the static method in both cases.

    0 讨论(0)
  • 2020-12-10 13:25

    I use number 1 (private INSTANCE) because you generally try to use the narrowest scope as possible. But in this case since the Holder class is private it doesn't really matter. However, suppose someone later decided to make the Holder class public then number 2 could be problematic from an encapsulation perspective (callers could bypass the getInstance() method and access the static field directly).

    0 讨论(0)
  • 2020-12-10 13:31

    There are several things to explain about singletons and the initialization-on-demand holder idiom. Here we go:

    1) The access modifier:

    Normally you can't access fields and methods in another class if they are private. They must at least be package private (having no modifier, it is) if the accessing class is in the same package. So the correct way to implement it, would be:

    public class Singleton {
        ...
        private static class LazyHolder {
            static final Singleton INSTANCE = new Singleton();
        }
        public static Singleton getInstance() {
            return LazyHolder.INSTANCE;
        }
    }
    

    However, JLS 6.6.1 explains:

    Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

    That means, declaring the field INSTANCE as private still allows the access from inside the top level class Singleton. But the compiler must do some tricks to get around the private modifier: It inserts package private methods for getting and setting such a field.

    In fact, it does not matter, which modifier you place on it. If it is public, it still cannot be accessed from other classes than Singleton. However ... I think the package private access is the best. Making it public does not makes sense. Making it private forces the compiler to do some tricks. Making it package private reflects what you have: Access to a class member from another class.

    2) How to implement a singleton:

    If you ever want to consider serialization, the singleton implementation will get a bit difficult. Joshu Bloch wrote a great section in his book "Effective Java" about implementing singletons. At the end, he concluded to simply use an enum for this, as the Java enum specification provides every charecteristic that is needed in regards to singletons. Of course, that does not use the idiom anymore.

    3) Considering design:

    In most design decisions, singletons do not have their places anymore. In fact, it could indicate a design issue, if you must place a singleton into your program. Keep in mind: Singletons provide a global acess mechanism to some data or services. And this is not OOP.

    0 讨论(0)
提交回复
热议问题