单例设计模式基本要求:一个类只允许产生一个实例化对象
实例化对象的方法有很多种:
1.一般情况下实例化对象
(1)普通情况下实例化对象
class Singleton{
public void print() {
System.out.println("普通情况下实例化对象");
}
}
public class SingletonTest {
public static void main(String[] args){
//实例化对象,实例化同时调用了Singleton的无参构造函数
Singleton singleton = new Singleton();
singleton.print();
}
}
2.若构造函数用private声明时,在类中实例化对象或者使用static关键字
class Singleton{
/**在类的内部实例化对象
* 4.在类的内部实例化对象
* Singleton singleton = new Singleton();
* 此时对象singleton为普通属性,此时外部无法实例化对象
* 想办法:在Singleton类没有实例化对象时,也可以使用属性singleton
* 解决办法:static关键字!!
*/
//使用static关键字实例化对象
//5.static关键字
static Singleton singleton = new Singleton();
//1.私有化的无参构造函数
private Singleton(){
}
//2.
public void print(){
System.out.println("private构造下,用static实例化对象");
}
}
public class SingletonTest{
public static void main(String[] args){
/**
* 3.Singleton singleton = new Singleton();
* 由于类中声明了一个私有构造方法,默认无参构造不再产生
* 此时实例化会报错
*
* 构造方法一旦被私有化了,外部无法调用构造无法产生实例化对象,此时的类封闭
* 还行调用Singleton的print方法,必须实例化对象,在类的内部实例化
*/
//6.内部已经实例化好了,且声明为static,外部获得Singleton的实例化对象
Singleton outSingleton = Singleton.singleton;
outSingleton.print();
}
}
Singleton类中的属性用private封装,提供getter方法。由于Singleton类无法在外部中实例化对象,因此getter方法也要声明为static
3.使用static的getter方法获取实例化对象
//使用static的getter方法获取实例化对象
class Singleton{
private static Singleton singleton = new Singleton();
private Singleton(){
}
//1.声明static的getter方法
public static Singleton getSingleton(){
return singleton;
}
public void print(){
System.out.println("private构造下,static的getter方法获取实例化对象");
}
}
public class SingletonTest{
public static void main(String[] args){
//外部获取Singleton对象属性
Singleton outSingleton = Singleton.getSingleton();
outSingleton.print();
}
}
上面的各种操作目标只有一个:在类中只产生一个实例化对象
此时想到单例设计模式:
单例模式两个典型场景:饿汉式、懒汉式
(1)饿汉式
class Singleton{
//饿汉式:一开始就准备好方法了,用final修饰属性,防止其被修改
private static final Singleton singleton = new Singleton();
private Singleton(){
}
//static的getter方法
public static Singleton getSingleton(){
return singleton;
}
public void print(){
System.out.println("饿汉式单例设计模式");
}
}
public class SingletonTest{
public static void main(String[] args){
Singleton outSingleton = Singleton.getSingleton();
outSingleton.print();
}
}
(2)懒汉式
注意:懒汉式存在线程不安全问题,而饿汉式不存在这一问题
class Singleton{
//懒汉式:一开始并没有准备好
//由于final修饰的变量声明时就必须初始化,
// 而懒汉式一开始是没有准备好的,所以此处的singleton不用final修饰
private static Singleton singleton;
private Singleton(){
}
public static Singleton getSingleton(){
if(singleton == null){
return new Singleton();
}
return singleton;
}
public void print(){
System.out.println("这是懒汉式单例设计模式");
}
}
public class SingletonTest{
public static void main(String[] args){
Singleton outSingleton = Singleton.getSingleton();
outSingleton.print();
}
}