单例设计模式
单例:唯一的实例,在整个Java系统中,某个类的对象只有唯一的一个。
形式:
1、饿(恶)汉式
无论使用者是否要用这个对象,都先创建这个对象。
2、懒汉式
只有在使用者来获取这个对象时,才会创建这个对象。
无论哪一种单例设计模式的写法:
(1)这个类的构造器是私有化 -->保证我们的使用者不能随意的创建第二个对象…
(2)这个唯一的实例必须在本类中创建,并且要用一个静态的变量来存储。
一、饿汉式
1、用一个公共的静态的常量来保存这个唯一的实例对象
2、枚举类
3、用一个私有的静态的常量来保存这个唯一的实例对象,再用一个静态方法返回这个唯一的对象
class Hungry{
//(2)用一个静态的变量,来存储这个唯一的对象
//这个对象是在类初始化时就创建了
public static final Hungry INSTANCE = new Hungry();
//(1)构造器私有化
private Hungry(){
}
}
enum HungryEnum{
INSTANCE
}
class HungryDemo{
//(2)用一个静态的变量,来存储这个唯一的对象
//这个对象是在类初始化时就创建了
private static final HungryDemo INSTANCE = new HungryDemo();
//(1)构造器私有化
private HungryDemo(){
}
public static HungryDemo getInstance(){
return INSTANCE;
}
}
二、懒汉式
class Lazy{
//(2)用一个静态的变量来保存这个唯一的实例
private static Lazy instance;//这里不能new
//(1)构造器私有化
private Lazy(){
}
//对的
/* //(3)当你来获取这个对象的时候,再来创建
public synchronized static Lazy getInstance(){
if(instance == null){
instance = new Lazy();
}
return instance;
}*/
//(3)当你来获取这个对象的时候,再来创建
public static Lazy getInstance(){
if(instance == null){//外面这个条件的作用是为了提高效率 当这个对象已经创建过了,那么后面的线程,无论多少个,就没必要等待锁
synchronized (Lazy.class) {//Lazy.class获取当前类的Class对象
if(instance == null){//里面的条件是为了安全
instance = new Lazy();
}
}
}
return instance;
}
class LazyDemo{
//(1)构造器私有化
private LazyDemo(){
}
//内部类
private static class Inner{
//(2)用静态内部类的一个静态的常量来保存这个唯一的对象
public static final LazyDemo INSTANCE = new LazyDemo();
static{
System.out.println("内部类的静态代码块");
}
}
//当我们调用这个方法时,获取外部类对象,才会导致内部类的加载和初始化,才会导致INSTANCE对象的创建,所以也属于懒汉式
public static LazyDemo getInstance (){
return Inner.INSTANCE;
}
//为了测试内部类是否被加载的方法
public static void test(){
System.out.println("外部类的静态方法");
}
}