------- 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方法),会出现对象不唯一的问题。