单例设计模式
案例:Singleton和SingletonTest类的框架实现(重中之重)---------> 有关static关键字
-
编程实现Singleton类的封装。
-
编程实现SingletonTest类对Singleton类进行测试,要求main方法中能得到且只能得到该类的一个对象。
/* 编程实现Singleton类的封装 */ public class Singleton { // 2.声明本类类型的引用指向本类类型的对象,使用private static关键字共同修饰 private static Singleton sin = new Singleton(); // 私有化之后需要通过引用.构造方法访问,而测试类无法new对象,故而使用static提升其层级从对象层级提升为类层级,下面的getInstance()方法也是如此。 // 1.私有化构造方法,使用private关键字修饰, 这样就让测试类中无法调用构造方法,也就无法new出任何哪怕一个的Singleton对象 private Singleton() {} // 3.提供公有的get方法负责将对象返回出去,使用public static关键字共同修饰 public static Singleton getInstance() { return sin; } } /* 编程实现Singleton类的测试 */ public class SingletonTest { public static void main(String[] args) { // 1.声明Singleton类型的引用指向该类型的对象 //Singleton s1 = new Singleton(); //Singleton s2 = new Singleton(); //System.out.println(s1 == s2); // 比较变量s1的数值是否与变量s2的数值相等 false //Singleton.sin = null; 可以使得引用变量无效 故而需要在类中私有化它 Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); // true } }
执行流程和内存结构分析
代码写完之后会放在硬盘中,只有当我们通过 java 执行这段代码的时候才会将其加载到内存中,而加载到内存中就会把它们的字节码文件放在方法区中。在加载Singleton类的时候,我们的代码是从上到下依次解析的,在Singleton类中声明了一个静态成员变量,静态变量隶属于类层级并被所有对象共享的,所以静态成员它所在的内存空间依然是在方法区。而当我们new对象的时候,只要是new出来的都是在内存空间中的堆区申请了一块内存空间。然后把堆区的内存空间地址记载到了sin这个变量中。
单例设计模式
- 在某些特殊场合中,一个类对外提供且只提供一个对象时,这样的类叫做单例类,而设计单例的流程和思想叫做单例设计模式。
单例设计模式的实现流程
- 私有化构造方法,使用private关键字修饰。
- 声明本类类型的引用指向本类类型的对象,并使用private static 关键字共同修饰。
- 提供公有的get方法负责把对象返回出去,并使用public static关键字共同修饰。
单例设计模式的实现方式
-
单例设计模式的实现方式有两种:饿汉式(代码只要一运行起来就会立刻马上创建对象) 和 懒汉式,在以后的开发中推荐懒汉式(考虑到多线程的抢占共享资源的问题)。现在只要记住,我们宁可当个 饿汉 ,不要当个 懒汉。
/* 编程实现Singleton类的封装 */ public class Singleton { // 2.声明本类类型的引用指向本类类型的对象,使用private static关键字共同修饰 //private static Singleton sin = new Singleton(); // 饿汉式 这个代码只要一运行起来就会立刻马上创建对象 private static Singleton sin = null; // 懒汉式 这不会立刻创建对象,当有人调用getInstance方法时才会创建,当然也不能创建多了,只有当sin的值为null的时候才需要创建 // 当调用方法才创建对象的写法叫做懒汉式 // 1.私有化构造方法,使用private关键字修饰, 这样就让测试类中无法调用构造方法,也就无法new出任何哪怕一个的Singleton对象 private Singleton() {} // 3.提供公有的get方法负责将对象返回出去,使用public static关键字共同修饰 public static Singleton getInstance() { //return sin; if(null == sin) { sin = new Singleton(); } return sin; } }