public class Demo1
{
public static void main(String[] args){
/*
1.实现单例模式第一个需要解决的问题在于Single类以外的类中不能任意的
用new调用Single的构造器来随意的创建对象 ------将构造方法私有化
Single s1 = new Single();//错误: Single() 在 Single 中是 private 访问控制
Single s2 = new Single();//错误: Single() 在 Single 中是 private 访问控制
System.out.println(s1 + " " + s2);//Single@1db9742 Single@106d69c
System.out.println(s1 == s2);//false
*/
/*
4-1.现在单例模式已经实现了,但是直接 类名.变量名 去获取在Single类中创建的
Single类的对象的这个静态变量时是将变量直接对外暴露的,不安全,所以使用java中的
封装:
Single s1 = Single.single;
Single s2 = Single.single;
System.out.println(s1 + " "+ s2);//Single@1db9742 Single@1db9742
System.out.println(s1 == s2);//true
*/
Single s1 = Single.getSingle();
Single s2 = Single.getSingle();
System.out.println(s1 + " "+ s2);//Single@1db9742 Single@1db9742
System.out.println(s1 == s2);//true
}
}
/*
单例模式实现的核心是static修饰符:
private static Single single = new Single();
1)被static修饰的变量随着类的第一次访问类被加载而产生,随着JVM的关闭类的销毁
销毁而销毁;即类只会被加载一次,所以在Single类中创建的Single类自己对象的静态
变量只new一次,即就只有一个对象;
2)静态变量存储于方法区的静态区(共享区),是被共享的,所以拿到的Single类中创建的
Single类自己对象的静态变量是同一个对象;
*/
class Single
{
private Single(){}
/*
2.现在在Single类以外的类中不能new构造器去创建Single类的对象,那么该怎么
去创建Single类的对象呢?
Single类的构造器现在只能在Single类中访问,所以就在Single类中去用new 构造器
来创建Single类自己的对象并把其作为其成员变量。
3.在Single类中创建的Single类自己的对象是作为其成员变量存在的,成员变量
是通过 对象.变量名 来访问,而现在外类不能拿到Single类的对象,也就不能拿到Single
类中创建的自己的对象这个成员变量了;
那么该怎么在Single类中创建这个成员变量呢? --- 通过静态化,在Single类以外
的类中就可以使用类名去访问了,就不需要Single的对象了
[类名.变量名]。
*/
private static Single single = new Single();
/*
4-2.将在Single类中创建的Single类自己的对象的静态变量私有化,然后给其
提供一个公共的访问方法;
5.为在Single类中创建的Single类的对象的静态变量提供的公共的访问方法
还必须静态化,因为Single类以外的类是拿不到Single类的对象的,就无法去通
过 对象.方法名 来访问这个公共的方法,所以只能将公共的方法静态化,然后使用
类名.方法名 去访问.
*/
public static Single getSingle(){
return single;
}
}
public class Demo2
{
public static void main(String[] args){
SingleB s1 = SingleB.getSingle();
SingleB s2 = SingleB.getSingle();
System.out.println(s1 + " "+ s2);//Single@1db9742 Single@1db9742
System.out.println(s1 == s2);//true
}
}
/*
单例模式的饿汉式
*/
class SingleA
{
//Single类一加载,Single类定义的自己的对象的静态变量就被实例化了
private SingleA(){}
private static SingleA single = new SingleA();
public static SingleA getSingle(){
return single;
}
}
/*
单例模式的懒汉式
*/
class SingleB{
private SingleB(){}
//1)先在Single类中声明Single类自己的对象的静态变量
private static SingleB single = null;
/*
2)当第一次调用getSingle()方法时,判断对象sigle是null,就对其进行实例化;
而在Single类中定义的Single类自己的对象的静态变量是处于方法区的中的静态区的,
所以始终是同一个静态变量;那么二次及二次以后再调用getSingle()
方法,在判断静态变量single已经不是null,就不再进入if语句对应其实例化了,
而是直接返回,所以仍然是同一个静态变量。
*/
public static SingleB getSingle(){
if(single == null){
single = new SingleB();
}
return single;
}
}