Java 单例模式
单例模式
单例模式Singleton
当一个类的方法要被大量用户同时调用时
一般用户都会先创建这个类的对象再通过对象调用类中的方法
但是对象是存放在堆内存中的,方法在栈内存中临时存储
同时刻大量的同样的对象的调用,还没等用户执行方法,内存可能就被堆满了,这样不好
那么,能不能让一个类只能创建一个对象呢?于是,单例模式有了,可以有效减少内存占用空间
单例模式的代码
代码很简单
public class Singleton {
private Singleton(){}
private static Singleton single = new Singleton();
public static Singleton getSingleton(){
return single;
}
}
测试一这个代码
public class Demo {
public static void main(String[] args){
Singleton s1 = Singleton.getSingleton();
Singleton s2 = Singleton.getSingleton();
System.out.println(s1);
System.out.println(s2);
}
}
运行结果:
可以看出创建的两个对象指向同一个地址,说明单例模式的代码成功了
单例模式代码的分析
首先我们要让用户调用这个类,只能创建一个对象,怎么弄呢?
一:构造方法私有
private Singleton(){}
一般,我们都是通过new
关键字,调用类的无参数构造方法,来创建类的对象
而我们是想要当前类只能产生唯一的一个对象,那么首先怎么禁止用户调用new
方法呢?
一般我们写的构造方法都是public
,用户可以通过new
调用构造方法来创建对象
那么,把构造方法变成private
就好
这样至少,用户不能new
一次就创建一个对象,用户不能在类的外面随意创建对象
二:用属性创建对象
private static Singleton single = new Singleton();
而单例,不是无例(在本类的某个成员位置上创建唯一的一个对象)
然后,我们有四种选择(属性,方法,构造方法,程序块)
- 构造方法:首先排除,已经私有化了,本身就是这个构建过程
- 程序块:也不行,程序块没有返回值,创建了对象也没法给别人使用
- 方法:也不行,因为,每一次执行这个方法,都会产生一个对象,保证不了唯一
- 属性:于是,只能用属性了
三:属性需要是静态的
因为,我们需要这个属性产生对象,只加载一次,需要用到static
关键字
四:属性需要是私有的
如果这个属性的权限不是私有的,非常不安全,用户可以在外部调用它,然后把他改掉(如果用户调用这个属性,给它赋值 null ,那这个方法就完了)
五:需要一个静态的,公有的方法去得到这个静态的,私有的属性
就是这:
public static Singleton getSingleton(){
return single;
}
然后,为什么这个给用户调用的方法是static
的呢?
因为,用户不能通过new
关键字来创建对象,从而调用方法
那么只能通过类名来调用类方法了
单例模式的实现
有三种形态,指的是对象的加载:
- 饿汉式(立即加载,对象启动时就加载)
- 懒汉式(延迟加载,对象什么时候用了再加载)
- 生命周期托管(单例对象别人帮我们处理,对象加载过程交给别人)
饿汉式就是上面给的代码
优点:不会产生对象没有就拿来使用的问题(如空指针异常)
缺点:启动项目加载的对象过多,有些还没有使用,产生服务器承载压力的问题
public class Singleton {
private Singleton(){}
private static Singleton single = new Singleton(); //对象启动时就加载
public static Singleton getSingleton(){
return single;
}
}
懒汉式代码如下
优点:启动项目时候只有需要的加载,不需要的还没有创建,不会浪费空间
缺点:可能由于没有操作好,导致异常(很严重)
public class Singleton {
private Singleton(){}
private static Singleton single;
public static Singleton getSingleton(){
if(single == null){
single = new Singleton(); //延迟加载的方式
}
return single;
}
}
本文地址:https://blog.csdn.net/Zhangguohao666/article/details/101033517