单例设计模式:
单例设计模式中解决的问题就是:可以保证一个类在内存中对象的唯一性。如果在对于多个程序使用同一个配置信息对象时,就需要保证对象的唯一性。
如何保证对象的唯一性呢?
- 不允许其他程序用new创建该类对象。
- 在该类中创建一个本类实例。
- 对外提供一个方法让其他程序可以获取该对象。
步骤:
- 私有化该类的构造函数。
- 通过new在本类中创建一个本类对象。
- 定义一个公有方法,将创建的对象返回。
两种设计模式:
饿汉式:(开发时用的比较多)
类一加载对象就已经存在了。
class Single
{
private static Single s=new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}
懒汉式:(面试时用的比较多)
类延迟加载进来,没有对象,只有调用getInstance方法时,才会创建对象。
class Single
{
private Single(){}
private static Single p=null;
public static getInstance()
{
if(p!=null)
p=new Single();
return p;
}
}
在两种方法中将类中的对象与对象的获取方法都定义成静态的是因为其他类中不能创建该类的对象,但是又为了调用该类的方法返回该类的对象,所以将其都定义成静态的方便使用类名之间调用。
补充:为什么在本类中实例化本类静态对象不会产生栈溢出呢?
通常来讲如下代码:
public class Test {
public Test t = new Test();
public static void main(String[] args) {
Test t1 = new Test();
}
}
一般会在运行时会提示StackOveflowError,由于在main函数中new Test对象的时候,Test对象在初始化自己成员的时候又会new一个Test对象,然后new Test对象的时候,Test对象在初始化自己成员的时候又会new一个Test对象这样循环往复,会不断在堆中开辟内存,在栈中调用构造函数,导致栈内存溢出。
如果将本类对象中实例化的对象定义成静态的:
public class Test {
public static final Test t = new Test();
public static void main(String[] args) {
Test t1 = new Test();
}
}
这样运行时就不会报错,由于main函数中在new Test对象之前,Test类加载进来的时候静态对象t已经被存放在本地方法区中了。当main函数new Test对象的时候,Test对象初始化自己的成员的时候不会再new Test对象了,因为在类加载进来的时候new出来的静态对象t已经存放在本地方法区中了,由于是静态的只会被创建一次,在接下来实例化Test对象的时候都不会被创建了。