黑马程序员——单例设计模式

------- android培训java培训、期待与您交流! ----------

        单例设计模式是为了解决:一个类在内存中只存在一个对象的问题。在单例设计模式中,有两种方式:懒汉式和饿汉式,下面分别讲解这两种方式。不论是哪种方式,实现的步骤都一样,步骤如下:

1.  将构造函数私有化;

2. 在类中创建一个本类对象;

3. 提供一个方法,用于获取到该对象。

下面通过例子Person类例子,分别分析“懒汉式”和“饿汉式”这两种单例设计模式。该Person类中有两个成员变量name和age。

单例设计模式方式一:饿汉式

        之所以称之为”饿汉式“,是因为先初始化对象,类进入内存时就已经存在对象。请看下面的例子,为了实现一个类在内存中只有单个对象的目标,在Person类中私有化构造方法,这样可以避免外界调用构造方法创建Person类的对象。但是,外界需要使用该类的成员方法操作成员变量,不创建对象如何调用成员方法呢?解决的方法是在Person类的内部创建唯一的一个Person类的对象p,并且提供获取该对象的方法getPerson(),该方法必须是静态的,因为静态的方法可以通过类名调用,如果不是静态的方法就需要使用对象来调用,但是外界无法创建该类对象,这就是为什么获取对象的方法getPerson()必须是静态的。而且,在类的内部创建的对象p也必须是静态的,因为静态方getPerson()只能访问静态的成员变量。代码例子如下,主函数中输出如下,通过该结果我们也可以证明代码例子中对象p1和p2指向同一块内存空间,也就是指向同一个对象。

控制台输出结果:

Teacher : 25
Teacher : 25

代码:

package com.itheima.entranceExam.blog;

class Person {
	//姓名
	private String name;
	//年龄
	private int age;
	
	//创建本类对象,必须是static的
	static Person p = new Person();
	
	//返回本类对象,该对象只有一个,该方法必须是静态static的
	public static Person getPerson() {
		return p;
	}
	
	//私有化构造方法
	private Person() { }

	//获取姓名
	public String getName() {
		return name;
	}

	//设置姓名
	public void setName(String name) {
		this.name = name;
	}

	//获取年龄
	public int getAge() {
		return age;
	}

	//设置姓名
	public void setAge(int age) {
		this.age = age;
	}
	
}

public class PersonTest {

	public static void main(String[] args) {

		//获取Person对象
		Person p1 = Person.getPerson();
		Person p2 = Person.getPerson();
		
		p1.setName("Student");
		p1.setAge(23);
		
		p2.setName("Teacher");
		p2.setAge(25);
		System.out.println(p1.getName()+" : "+p1.getAge());
		System.out.println(p1.getName()+" : "+p1.getAge());
	}
}


单例设计模式方式二:懒汉式

        ”懒汉式“就是当类加载进内存时,还不存在类的对象,只有当调用get对象方法时,才创建对象,这种方式也叫做对象的延时加载,昵称为“懒汉式”。

        下面通过代码分析”懒汉式“单例设计模式,代码如下。我们知道,”懒汉式“只有在调用getPerson方法时才创建Person对象,为了实现这个目的,我们在创建Person类对象引用p时,不能new创建对象,而是将p初始化为null(第10行),然后在getPerson方法中再new对象。但是,为了避免出现创建多个对象的问题,必须要在getPerson方法中先判断p是否为空(第15行)。如果不为空说明该对象已经创建,则不让创建,如果为空则说明是第一次创建该对象,允许创建该对象。如果不判断,就会造成创建多个对象的问题,这就不是单例设计模式了。下面的例子输出结果和上面的相同。

代码:

package com.itheima.entranceExam.blog;

class Person {
	//姓名
	private String name;
	//年龄
	private int age;
	
	//创建本类对象,必须是static的,初始化为空
	static Person p = null;
	
	//返回本类对象,该对象只有一个,该方法必须是静态static的
	public static Person getPerson() {
		//如果为空,说明还没有创建对象,这时候才可以创建对象
		if(p == null)
			p = new Person();
		return p;
	}
	
	//私有化构造方法
	private Person() { }

	//获取姓名
	public String getName() {
		return name;
	}

	//设置姓名
	public void setName(String name) {
		this.name = name;
	}

	//获取年龄
	public int getAge() {
		return age;
	}

	//设置姓名
	public void setAge(int age) {
		this.age = age;
	}
	
}

public class PersonTest {

	public static void main(String[] args) {

		//获取Person对象
		Person p1 = Person.getPerson();
		Person p2 = Person.getPerson();
		
		p1.setName("Student");
		p1.setAge(23);
		
		p2.setName("Teacher");
		p2.setAge(25);
		System.out.println(p1.getName()+" : "+p1.getAge());
		System.out.println(p1.getName()+" : "+p1.getAge());
	}
}

“饿汉式”和“懒汉式”的区别在于:饿汉式在类加载进内存时,对象就已经存在,懒汉式则是在需要时才创建对象。在实际开发过程中,建议使用”饿汉式“单例设计模式,因为”懒汉式“存在安全问题,当多个线程同时调用该方法时(getPerson方法),会出现对象不唯一的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值