4.3、单例设计模式 (重量级)
-
什么是设计模式?
-
静态方法和属性的经典使用
-
设计模式是在大量的实践中总结和理论化之后优选的代码结构,编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己在思考和摸索
-
-
什么是单例模式?
-
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类,只能存在一个对象实例,并且该类只能提供一个取得其对象实例的方法
-
单例设计模式有两种:1) 饿汉式 2)懒汉式
-
4.3.1、饿汉式
- 饿汉式实现步骤如下:
-
构造器私有化 --------> 防止直接new对象
-
类的内部创建对象------------>该对象是static用于后面方法对 对象的调用
-
向外暴露一个静态的公共方法。-------------------------> getInstance
- 代码示例:
java
public class text08 {
public static void main(String[] args) {
GrilFriend instance = GrilFriend.getInstance();
System.out.println(instance);
}
}
//只能有一个女朋友!
class GrilFriend{
private String name;
//2、在内部创建对象
private static GrilFriend gf = new GrilFriend("小花花");
// 1、构造器私有化
private GrilFriend(String name) {
this.name = name;
}
//3、向外暴露一个静态的公共方法
public static GrilFriend getInstance() {
return gf;
}
@Override
public String toString() {
return "GrilFriend{" +
"name='" + name + '\'' +
'}';
}
}
输出:
GrilFriend{name='小花花'}
个人总结:
-
为什么叫饿汉式?
可以理解为,类的内部对象,在类加载的时候,就可能创建好了,显得很着急,所以叫饿汉式。
-
如果两次调用返回gf对象的静态方法,返回的地址是一样的吗?为什么?
答:一样!
-
需要注意:
1、这里其实我们可以发现关系很紧密,因为单例模式只允许一个对象实例,所以要把构造器私有化,构造器私有化了,还要保证一个对象实例,就需要在对象的内部创建,并且用static修饰,以便于后面静态方法的调用(静态只能调用静态)。
2、如果两个都不加static,那么岂不是我又可以在外面创建对象去调用了
4.3.2、懒汉式
为了避免饿汉式,可能创建了对象,但是没用这种资源浪费,引出了懒汉式。
-
步骤:
-
1、构造器私有化
-
2、定义一个static静态属性对象
-
3、提供一个public的static方法,可以返回一个Cat对象
-
4、懒汉式,只有当用户使用getInstance时,才返回cat对象,后面再次调用时,会返回上次创建的cat对象,从而保证单例
-
代码示例:
java
public class text09 {
public static void main(String[] args) {
Cat instance = Cat.getInstance();
System.out.println(instance);
}
}
class Cat{
private String name;
private static Cat cat;
//步骤
//1、构造器私有化
//2、定义一个static静态属性对象
//3、提供一个public的static方法,可以返回一个Cat对象
//4、懒汉式,只有当用户使用getInstance时,才返回cat对象,后面再次调用时,会返回上次创建的cat对象,从而保证单例
private Cat(String name){
System.out.println("我是构造器");
this.name = name;
}
public static Cat getInstance(){
if(cat == null){
cat = new Cat("cat");
}
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
与饿汉式的区别是不会因为调用某个静态变量,就去创建对象。
public static Cat getInstance(){
if(cat == null){
cat = new Cat("cat");
}
return cat;
}
因为这段代码的存在,所以不会因为调用某个静态属性就创建了对象。
- **还可能会有疑问:**因为getInstance方法 也是static修饰的,不会在类加载的时候就执行吗?
答: 被static修饰的静态成员会随着类的加载而加载,但是仅是去加载到 "方法区",在没有调用的时候,并不会去执行的。如果每次类加载的时候都自动执行方法,那岂不是乱套了。(个人理解)
4.3.3、饿汉式 VS 懒汉式
-
两者区别在于创建对象的时机不同,饿汉式是在类加载的时候创建的的。懒汉式是使用时才创建。
-
饿汉式的问题: 在类加载的时候就创建,可能存在资源的浪费
-
懒汉式的问题:线程安全问题。
-
在JavaSE标准类中,java.lang.Runtime就是经典的单例模式
以上是就是单例设计模式的学习记录笔记,欢迎小伙伴留言~~~