目录
设计模式
单例模式
一、饿汉式
二、懒汉式
三、饿汉式VS懒汉式
总结
设计模式
1.静态方法和属性的经典使用
2.设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索
单例模式
类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
一、饿汉式
一般情况下创建对象的代码
package com.hspedu.single_;public class SingleTon01 {public static void main(String[] args) {GirlFriend gf1 = new GirlFriend("小红");GirlFriend gf2 = new GirlFriend("小黄");}
}
class GirlFriend {private String name;public GirlFriend(String name) {this.name = name;}
}
构造器私有化,构造器私有化之后无法在main方法内创建新对象
private GirlFriend(String name) {
this.name = name;
}
解决方法
1.构造器私有化
2.在类中创建新对象
3.创建public static 方法,在方法中return创建的新对象
4.在main方法中通过类名.方法名调用上述方法
package com.hspedu.single_;public class SingleTon01 {public static void main(String[] args) {
// GirlFriend gf1 = new GirlFriend("小红");
// GirlFriend gf2 = new GirlFriend("小黄");//调用静态方法,获取对象,接收返回的对象//调用静态方法,导致类加载,类加载只会进行一次GirlFriend gf1 = GirlFriend.getInstance();//输出对象,格式 全类名 + @ + 哈希值的十六进制System.out.println(gf1);System.out.println(gf1);}
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend {private String name;//如何保障我们只能创建一个GirlFriend对象//单例模式-饿汉式//1.构造器私有化(防止new对象)//2.类的内部创建对象(static对象)//3.提供一个public static 方法,返回上述创建的对象//因为要在static方法中return,所以必须是static修饰private static final GirlFriend gf = new GirlFriend("小红");private GirlFriend(String name) {this.name = name;}//必须是static方法,因为构造器私有化,无法通过对象名.类名调用,只能通过类名.方法名调用public static GirlFriend getInstance(){return gf;}@Overridepublic String toString() {return "GirlFriend{" +"name='" + name + '\'' +'}';}
}
饿汉式的名称由来:在类加载的时候就已经创建好了对象,不论调用不调用,都已经创建好了
eg:
package com.hspedu.single_;public class SingleTon01 {public static void main(String[] args) {System.out.println(GirlFriend.n1);}
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend {private String name;public static int n1 = 100;//如何保障我们只能创建一个GirlFriend对象//单例模式-饿汉式//1.构造器私有化(防止new对象)//2.类的内部创建对象(static对象)//3.提供一个public static 方法,返回上述创建的对象//因为要在static方法中return,所以必须是static修饰private static final GirlFriend gf = new GirlFriend("小红");private GirlFriend(String name) {System.out.println("构造器被调用");this.name = name;}//必须是static方法,因为构造器私有化,无法通过对象名.类名调用,只能通过类名.方法名调用public static GirlFriend getInstance(){return gf;}@Overridepublic String toString() {return "GirlFriend{" +"name='" + name + '\'' +'}';}
}
上述代码调用了静态变量n1,完成了类加载,所以对象gf也被创建了
二、懒汉式
等用到的时候再创建对象
package com.hspedu.single_;public class SingleTon02 {public static void main(String[] args) {//调用静态方法,cat的默认值为null//执行 cat = new Cat("圆圆");Cat instance = Cat.getInstance();System.out.println(instance);//再次调用静态方法getInstance()//经过上述操作,对象cat 已经 ≠ null//不会再创建新对象,还是输出“圆圆”Cat instance1 = Cat.getInstance();System.out.println(instance1);}
}
class Cat{private String name;private static Cat cat;//对象为引用//构造器私有化//定义一个静态属性:对象//提供一个public static 方法,返回对象private Cat(String name) {System.out.println("构造器被调用");this.name = name;}public static Cat getInstance(){if(cat == null){cat = new Cat("圆圆");}return cat;}@Overridepublic String toString() {return "Cat{" +"name='" + name + '\'' +'}';}
}
只有一个对象实例,第二次调用的时候输出的还是第一次创建的对象实例,因此,构造器也只会调用一次
三、饿汉式VS懒汉式
二者最主要的区别在于
1.创建对象的时机不同: 饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建。
2.饿汉式不存在线程安全问题,懒汉式存在线程安全问题。(线程还没学到)
3.饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。
4.在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式
代码
public class Runtime {//私有的static属性:变量;在类加载的时候就会创建,饿汉式private static final Runtime currentRuntime = new Runtime();private static Version version;//public static 方法 返回currentRuntimepublic static Runtime getRuntime() {return currentRuntime;}//构造器私有化private Runtime() {}
}
总结
1.单例模式的两种实现方式(1) 饿汉式(2) 懒汉式
2.饿汉式的问题:在类加载时候就创建,可能存在资源浪费问题
3.懒汉式的问题: 线程安全问题,后面学了线程后,再进行完善