目录
设计模式
单例模式
一、饿汉式
二、懒汉式
三、饿汉式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;
}
@Override
public 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;
}
@Override
public 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;
}
@Override
public 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 方法 返回currentRuntime
public static Runtime getRuntime() {
return currentRuntime;
}
//构造器私有化
private Runtime() {}
}
总结
1.单例模式的两种实现方式(1) 饿汉式(2) 懒汉式
2.饿汉式的问题:在类加载时候就创建,可能存在资源浪费问题
3.懒汉式的问题: 线程安全问题,后面学了线程后,再进行完善