这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战
这似乎是很多面试喜欢考的题,让面试者手写一个单例模式的实现。众所周知,茴香豆的茴字有4种写法,单例模式有7种写法。但茴香豆的case似乎是在讽刺,单例模式从技术原理上说并不是,只是不同场景可以用不同的实现,但有些写法是性能又好又安全,其他的写法似乎就没有必要了。
扯远了,还没有说单例模式的优势。这可能是这些设计模式中最好理解的一种,不用画类图,有些类全局使用,而且基本没有动态的东西,那么全局只创建一次就好了,就像spring的bean,就是单例的。毕竟某些固定的对象创建还是挺费事费力的,那么单例要做到的就是保证它确实只被创建一次,即使在多线程的环境下。另外就是,在某些场景下,有些类就只能创建一次,创建出第二个就会有bug,这也必须用到单例模式。
一般情况下,如果能写出以下的单例实现,就算这个问题过了。
public class SingletonObject {
private SingletonObject(){}
private static class InstanceHolder {
private final static SingletonObject instance = new SingletonObject();
}
public static SingletonObject getInstance() {
return InstanceHolder.instance;
}
}
这是一种静态内部类的实现方式,基于Java类加载的机制,InstanceHolder在被使用之前不会被加载,同时也实现了懒加载。但这样并不算绝对安全,因为还是可能被反射或者反序列化获取多个实例。
如果你恰好看过《effective java》,作者会推荐使用枚举来实现单例。为什么呢?因为这是规定,俗话说玩赖。枚举类在jvm中保证只存在一个实例,无论怎么操作,都不能再创造出第二个一样的枚举类型。同时,枚举的写法写起来也特别精简:
public enum SomeThing {
INSTANCE;
public String getSomething() {
return "SomeThing";
}
}