美文网首页
3.使用私有构造方法或枚类实现Singleton

3.使用私有构造方法或枚类实现Singleton

作者: Orange_____ | 来源:发表于2019-01-23 18:18 被阅读0次

    单例的类只有一个实例。即一个类只有一个对象实例
    常见实现单例的方法有两种, 两者都是基于构造器私有, 然后对外提供该类的实例作为静态变量

    第一种方法就是使用final修饰静态变量

    public class Foo {
    
        private Foo() {
        }
    
        public static final Foo foo = new Foo();
    
        public void doSomething() {
    
        }
    
    }
    

    构造方法被设置成私有的, 在类的内部初始化对象, 使用final保证只被初始化一次, 但是需要注意, 如果调用者使用反射来调用构造器来创建对象的话, 将会导致内存中出现两个实例对象, 对此避免的方法是使其在请求创建第二个实例时抛出异常。

    第二种方法是对外提供一个静态工厂方法, 静态成员变量私有化

    public class Foo {
    
        private Foo() {
        }
    
        private static Foo foo = new Foo();
    
        public static Foo getFoo() {
            return foo;
        }
    
        public void doSomething() {
    
        }
    
    }
    

    每次调用getFoo()都将返回同一个Foo实例

    静态工厂方法的一个优点是,它可以灵活地改变你的想法,无论该类是否为单例而不必更改其API。 工厂方法返回唯一的实例,但是可以修改,比如,返回调用它的每个线程的单独实例。 第二个好处是,如果你的应用程序需要它,可以编写一个泛型单例工厂(generic singleton factory )。 使用静态工厂的最后一个优点是方法引用可以用supplier,例如Foo::getFoo等同于Supplier<Foo>。 除非与这些优点相关的,否则公共属性方法是可取的。

    如果想序列化单例类, 仅仅将implements Serializable添加到声明中是不够的。为了维护单例的保证,声明所有的实例属性为transient,并提供一个readResolve方法。否则,每当序列化实例被反序列化时,就会创建一个新的实例,为了防止这种情况, 则需要将这个readResolve方法添加到单例所在类

    // readResolve方法用来提供单例对象
    private Object readResolve() {
        return foo;
    }
    

    最后一种实现单例的方法是声明单一枚举类

    public enum Foo {
        
        FOO;
    
        public void doSomething() {
        }
    
    }
    

    相关文章

      网友评论

          本文标题:3.使用私有构造方法或枚类实现Singleton

          本文链接:https://www.haomeiwen.com/subject/heesjqtx.html