系统中为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例。
定义与特点
一个类只能有一个实例,并且该类可以自行创建这个实例的一种模式。特点:只有一个实例对象;单例对象必须由单例类自行创建(不可以在其他类中new创建);单例类对外提供一个访问该单例的全局访问点。
一般结构
public class Singleton{
private static Singleton instance;//类型为自身的属性
private Singleton(){}//私有构造方法,使访问类(即其他调用单例类的外部类)无法通过调用构造方法创建实例
public Singleton getInstance(){}//创建或获取该单例类静态私有实例instance(单例类在程序中唯一的实例)。
}
单例模式的实现
懒汉式单例
类加载时没有生成单例,只有当第一次调用getInstance()方法时才去创建这个实例。
public class Singleton{
private static Singleton instance=null;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(this.instance==null){
this.instance=new Singleton();
}
return this.instance;
}
}
饿汉式单例
类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。
public class Singleton{
private static Singleton instance=new Singleton();
private Singleton(){};
public static Singleton getInstance(){
return instance;
}
}
静态内部类
兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久带的对象。
public class Singleton{
private Singleton(){}
public static class SingletonInner{
private static final Singleton instance=new Singleton();
}
public static Singleton getInstance(){
return SingletonInner.instance;
}
}
单例防止反射入侵
思路:再构造函数中只允许初始化一次即可
public class Singleton{
private static Singleton instance=new Singleton();
private static boolean flag=true;
private Singleton(){
if(flag){
flag=false;
}else{
throw new RuntimeException("单例模式被入侵!");
}
public static Singleton getInstance(){
return instance;
}
}
应用场景
- 当某个类只需要生成一个实例对象的时候;
- 当类的对象需要被共享时;
- 当类被频繁实例化,并且创建的对象又频繁被销毁。
评论区