单例模式
单例模式是 :一个类只允许产生一个实例化对象(如太阳类只有一个太阳对象)。
如何只产生一个是实例化对象?
- 构造方法私有化: 我们知道是构造函数是实例化对象,要只产生一个实例化对象,就需要把构造方法用private分装起来,那么外部就无法调构造方法。
- 在类里实例化一个私有全局静态对象:既然类外部无法实例化对象,就必须在类里实例化对象,而且对象需要是静态属性,如果不是静态,还得实例化对象取得这个属性,所以声明为静态,在类加载的时候就有这个对象。
- 一个静态公有的取得实例化对象方法:既然在类里实例化的对象是私有,就要有一个getXX方法来取得这个对象,同样这个方法需要是静态,在外部通过类名来调用。
单例模式又分为:饿汉模式和懒汉模式。
饿汉模式是只要加载类就会new一个对象,而懒汉模式是用到对象才new。
首先看饿汉模式代码:
package CODE;
//饿汉模式
class Person
{
private String name;
private static final Person person =new Person(); //实例化一个静态全局常量对象,
// 因为这个对象实例化出来不会再被改变,所以声明为final ,static final 是全局常量
private Person() //构造方法私有化
{}
public static Person getPerson()
{
return person;
}
}
public class Singleton
{
public static void main(String[] args)
{
Person person1=Person.getPerson();
Person person2=Person.getPerson();
Person person3=Person.getPerson();
System.out.println(person1); //CODE.Person@4554617c
System.out.println(person2); //CODE.Person@4554617c
System.out.println(person3); //CODE.Person@4554617c
//可以发现三个对象的地址是一样的,事实上只实例化了一个对象,三个引用指向同一块堆内部
}
}
懒汉模式:
class Person
{
private Person() //构造方法私有化
{}
private static Person person; //该成员变量默认值为null
public static Person getPerson()
{
if(person==null) //懒汉模式
{
person=new Person();
}
return person;
}
}
如果面试:推荐写饿汉式单例,因为懒汉式存在线程安全问题(可能会new 2个对象)。
多例模式:
多例模式指可以实例化出有限个对象。
多例和单例的区别是对象个数,那么在设计单例模式基础上需要加上以下步骤:
在类里定义有限个静态对象,用flag返回想要的对象,代码如下:
////多例模式
class Sex
{
private String sex;
public static final int MALE_FLAG=1;
public static final int FEMALE_FLAG=2;
private static final Sex male=new Sex("男");
private static final Sex femal=new Sex("女");
private Sex(String sex)
{
this.sex=sex;
}
public static Sex getSex(int flag) //定义一个falg,告诉要什么类型对象
{
switch(flag)
{
case MALE_FLAG:
return male;
case FEMALE_FLAG:
return femal;
default:
return null;
}
}
public String toString()
{
return this.sex;
}
}
public class Singleton
{
public static void main(String[] args)
{
Sex male=Sex.getSex(Sex.MALE_FLAG);
Sex female=Sex.getSex(Sex.FEMALE_FLAG);
System.out.println(male); //男
System.out.println(female); //女
}
}
其实多例模式我们只需要理解概念即可,多例模式已经被枚举取代。