使用私有构造函数强化singleton属性。 方法一:公有的静态成员是一个final域,成员的声明很清楚的表达了这个类是一个singleton。 public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { }
public void leaveTheBuilding() {
System.out.println("This is singleton.");
}
public static void main(String[] args) {
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBuilding();
}
}
私有的构造函数仅被调用了一次,用来实例化公有的静态final域Elvis.INSTANCE; 由于缺少公有的或者受保护的构造函数,所以保证了Elvis的全局唯一性。 一旦Elvis类被实例化之后,只有一个Elvis实例存在。 方法二:提供一个公有的静态工厂方法,而不是公有的静态final域。该方式提供了更大的灵活性,在不改变API的前提下,可以把该类改成singleton或者非
singleton的。 public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { }
public static Elvis getInstance() { return INSTANCE; }
public void leaveTheBuilding() {
System.out.println("This is singleton.");
}
public static void main(String[] args) {
Elvis elvis = Elvis.getInstance();
elvis.leaveTheBuilding();
}
}
总结:第一种方法效率稍微高一些,采用第一种方法实现singleton后,就没有改变的余地了,当你想把该类改成非singleton,显然是不行的了。 所以,除非确实该类是一个singleton,那就用第一个方法吧。用第2种方法的时候,假如该类实现了serializable接口,那应该重写readResolve()方法, 否则再反序列化的时候是会产生一个新的实例,这与singleton相违背了!
2.通过私有的构造函数强化不可实例化的能力.
在面向对象程序设计中,假如存在太多只有静态属性和静态方法的类;那么,面向对象的思想可能在这会损失殆尽。
但是,并不能说面向对象的程序中就不应该出现只有静态属性和静态方法的类,相反,有时候我们还必须写这样的类作为工具类。
这样的类怎么实现呢?有人可能会把该类定义成抽象类(Abstract class),的确,抽象类是不可以实例化的,但是别忘了还有继承,
继承了抽象类的子类在实例化时候,默认是会先调用父类无参数的构造函数的(super();),这时候,父类不是也被实例化了嘛?
其实我们可以这样做,把该类的构造函数定义为私有的(private),而类的内部又不调用该构造函数的话,就成功了。
这样带来的后果就是该类成了 final的,不可能再被任何类继承了,要被继承,得提供一个公有(public)的或者保护(protect)的构造函数, 这样才能被子类调用。
标签:singleton,java,私有,Elvis,final,实例,public,构造函数 From: https://blog.51cto.com/u_15928064/5984662