热爱技术,追求卓越
不断求索,精益求精

秒懂java单例模式,java私有构造器与一夫一妻制

在《秒懂java,对于创建一个java对象,你真的会吗?》一文中,讲述了java如何创建一个对象以及如何更优雅的创建对象。此外,java里还有一种比较特殊的创建对象的方式:私有构造器创建对象。

java私有构造器

私有构造器就是一个类的构造方法的访问权限定义为private,它只能被包含它的类自身所访问,而无法在类的外部调用,故而可以阻止对象的生成。这就好比现代社会的一夫一妻制,这个private的私有构造方法就类似这种约束制度,类就是一大老爷们,私有构造方法创建的对象就好比是这个大老爷们明媒正娶的老婆。

package cn.lovecto.test;

/**一夫一妻制*/
public class Monogamy {
    /**一个丈夫只允许有一个妻子*/
    public static class Husband{
        /**妻子的名字*/
        private String wife;
        /**丈夫唯一的妻子(一个husband只能有一个wife实例)*/
        private static final Husband WIFE = new Husband("wife");
        /**私有的构造方法时强有力的制度约束*/
        private Husband(String wife){
            this.setWife(wife);
        }
        /**在公共场合,是可以看到这个丈夫漂亮的老婆的*/
        public static Husband getInstance(){
            return WIFE;
        }
        /**妻子可以为丈夫生儿育女*/
        public Object baby(){
            return wife + "'s baby";
        }
        public String getWife() {
            return wife;
        }
        public void setWife(String wife) {
            this.wife = wife;
        }
    }
}

在上面的内部类Husband就是一个只有私有构造器的类。我们通常使用私有构造器这种手段来实现单例(Singleton)。Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

java反射对私有构造器的访问

本来一夫一妻制度挺好的,但是有时候丈夫经常在外面应酬,看见其他漂亮的女人也难免心动,经不住诱惑,于是就会出轨,就会有情人,就会有小三小四甚至还有了小孩。私有构造器的约束本来也是挺好的,但也不能完全做到一个类只有一个实例,我们可以通过Java反射机制来实现对类的私有构造方法的访问从而创建新的对象:

//一夫一妻制度下
System.out.println(Husband.getInstance().baby());
//反射机制导致丈夫出轨找到情人还生了孩子
Class clazz = Husband.class;
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
constructor.setAccessible(true);
Husband lover = (Husband)constructor.newInstance(new Object[]{"lover"});
System.out.println(lover.baby());

java私有构造实现单例多线程问题

上面的例子中,类加载的时候就会直接new一个静态对象出来,在不使用同步锁的情况下实现了线程安全,当系统中这样的类较多时,会使得启动速度变慢。由于一个男孩子不可能一出生就立刻找老婆,只有等到他达到法定结婚年龄后才会娶妻生子。到达法定结婚年龄从我们系统的角度叫“适时加载”,就是在第一次使用的时候才初始化该类对象:

/**一个丈夫只允许有一个妻子*/
public static class Husband{
    /**妻子的名字*/
    private String wife;
    /**丈夫唯一的妻子(一个husband只能有一个wife实例)*/
    private static Husband WIFE;
    /**私有的构造方法时强有力的制度约束*/
    private Husband(String wife){
        this.wife = wife;
    }
    /**对获取实例的方法进行同步*/
    public static synchronized Husband getInstance(){
        if(WIFE == null){
            WIFE = new Husband("wife");
        }
        return WIFE;
    }
}

上面的代码中,getInstance方法被锁住,如果调用这个方法的线程很多,将导致很多线程阻塞在这里,粒度有点大,我们只需要锁住创建对象的那部分即可,下面是改进的getInstance方法:

public static Husband getInstance(){
    if(WIFE == null){
        synchronized (Husband.class) {
            WIFE = new Husband("wife");
        }
    }
    return WIFE;
}

总结

java私有构造器是实现单例(Singleton)模式的有效形式,但在使用过程中要考虑多线程问题以及合适的时机创建对象。单例模式就类似于一夫一妻制,适时加载对象就好比要达到婚育年龄才允许结婚。看完这篇《秒懂java,java私有构造器与一夫一妻制》, 你是否get到了呢?

赞(2)
未经允许不得转载:LoveCTO » 秒懂java单例模式,java私有构造器与一夫一妻制

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

热爱技术 追求卓越 精益求精