前言
今天复习Java基础知识,正好看到了单例模式。惭愧的是,自己以前对单例模式一点都不清楚,现在重新学习了,自己写一下,梳理思路
单例模式简介
单例模式是Java设计模式中最简单的模式之一,单例模式涉及一个单一的类,在该类里创建一个自己的对象,并且这个对象是唯一的。该类必须提供一个访问这个唯一对象的方法,使得其他类可以直接访问这个对象,而不需要实例化对象
特点
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其它对象提供这个实例
单例模式的思路
1、首先我们建立一个单例类和单例类的测试类
建一个单例类,类中有一个无参构造方法和一个打印方法
/**
* @author MT
* 这是一个单例类
*/
public class Simpleton {
//这是一个无参构造方法
public Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
}
建一个单例类的测试类
/**
* @author MT
* 这是一个单例类的测试类
*/
public class TestDemo {
public static void main(String[] args) {
}
}
我们知道,在单例模式中,只有单例类创建的一个自己的对象,这样的话,其他类就不能实例化Simpleton
对象,那么如何限制其他类不能实例化Simpleton
对象呢?
2、构造方法私有化
在测试类中实例化一个Simpleton
类的对象时,代码为Simpleton inst = new Simpleton()
,其中Simpleton()指的是构造方法,构造方法的作用是对类进行初始化
我们把单例类中的构造方法的访问权限改成private
,变成私有,这样的话,这个类的构造方法只能在本类中调用,外部无法直接调用,即无法在外部调用实例化Simpleton
类的对象
public class Simpleton {
//这是一个无参构造方法
private Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
}
public class TestDemo {
public static void main(String[] args) {
Simpleton inst = null; //声明对象
inst = new Simpleton(); //错误:The constructor Simpleton() is not visible
inst.print(); //调用Simpleton中print方法
}
}
3、在单例类内部实例化本类对象
上面我们说,构造方法私有化,只能在本类中调用。而单例模式中的单例,指的是单个的实例化对象,这个对象存在于单例类中。那么我们在单例类中调用自己的构造方法,创建一个自己的对象,即创建“单例”
public class Simpleton {
Simpleton instance = new Simpleton(); //在内部实例化一个本类对象
//这是一个无参构造方法
private Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
}
对于一个类中的普通属性,默认情况下一定要存在了实例化对象后才可以进行调用,既然外部不能实例化Simpleton
对象,那么外部如何调用Simpleton
类中的instance
属性呢?
4、static关键字
static
关键字定义的属性表示类属性,保存在全局数据区,可以不经过实例化,直接被类名称调用,那么我们加上static
关键字,在测试类中,利用“类名.static属性”方法取得实例化对象
public class Simpleton {
static Simpleton instance = new Simpleton(); //在内部实例化一个本类对象
//这是一个无参构造方法
private Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
}
public class TestDemo {
public static void main(String[] args) {
Simpleton inst = null; //声明对象
inst = Simpleton.instance; //利用“类名.static属性”方法取得实例化对象
inst.print(); //调用Simpleton中print方法
}
}
5、提供一个外部访问的方式
第四步中通过static
关键字,已经可以实现外部的访问。但是属性都应该封装,我们来把instance
属性封装一下,然后用Simpleton.getInstance()
获取唯一可用的对象
public class Simpleton {
private static Simpleton instance = new Simpleton(); //在内部实例化一个本类对象
//这是一个无参构造方法
private Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
public static Simpleton getInstance() {
return instance;
}
public static void setInstance(Simpleton instance) {
Simpleton.instance = instance;
}
}
public class TestDemo {
public static void main(String[] args) {
Simpleton inst = null; //声明对象
/*inst = new Simpleton(); //错误:The constructor Simpleton() is not visible*/
/*inst = Simpleton.instance; //利用“类名.static属性”方法取得实例化对象*/
inst = Simpleton.getInstance(); //获取唯一可用的对象
inst.print(); //调用Simpleton中print方法
}
}
6、完成了吗?
本程序仍有一个问题,就是一下代码也可以使用,重新实例化对象之后,意味着之前做的都白费了,那么怎么解决呢?
public class Simpleton {
private static Simpleton instance = new Simpleton(); //在内部实例化一个本类对象
//这是一个无参构造方法
private Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
public static Simpleton getInstance() {
instance = new Simpleton(); //重新实例化对象
return instance;
}
public static void setInstance(Simpleton instance) {
Simpleton.instance = instance;
}
}
那就是增加一个final
关键字,相当于定义成常量,不可更改
7、完整代码
public class Simpleton {
private final static Simpleton instance = new Simpleton(); //在内部实例化一个本类对象
/*这是一个无参构造方法
* 构造方法私有化
*/
private Simpleton() {}
//这是一个打印方法
public void print() {
System.out.println("hello world");
}
//这是一个提供给外部访问instance的方法
public static Simpleton getInstance() {
return instance;
}
}
public class TestDemo {
public static void main(String[] args) {
Simpleton inst = null; //声明对象
/*inst = new Simpleton(); //错误:The constructor Simpleton() is not visible*/
/*inst = Simpleton.instance; //利用“类名.static属性”方法取得实例化对象*/
inst = Simpleton.getInstance(); //获取唯一可用的对象
inst.print(); //调用Simpleton中print方法
}
}
以后使用Simpleton
类时,不管代码如何操作,也永远只会存在一个Simpleton
类的实例化对象,而这样的代码,在设计模式上就称为单例设计模式
总结
以上简单的说明了单例模式的原理,关键词为:构造方法私有化(private
)、static
、单个实例
更多Java设计模式、单例模式其它实现方式及更多单例模式知识点击 这里