13、单例设计模式
单例设计模式:保证一个类仅有一个实例,并提供给一个访问它的全局访问点。
先说单例怎么写,后面说单例的好处、优点等
如何构造:
1、构造方法私有化
2、声明一个本类对象
3、给外部提供一个静态方法获取对象实例
两种实现方式:
1、饿汉式
public class a
{
public static void main(String[] args)
{
}
}
class Singleton
{
private Singleton(){}; //构造方法私有化
private static Singleton s = new Singleton(); //可以在Singleton中自己声明一个s对象(声明本类对象)
public static Singleton getInstance()
{
return s; //这个方法是给外部提供一个静态方法获取对象实例
}
//上面,Singleton的设计方法就完成了
public void print()
{
System.out.println("测试方法");
}
}
这个时候,在主函数中写Sengleton s = new Singleton();会报错,因为下面的类中已经把Singleton私有化了。
public class a
{
public static void main(String[] args)
{
Singleton s = Singleton.getInstance(); //先获取一个实例
s.print();
System.out.println();
Singleton ss = Singleton.getInstance(); //先获取一个实例
ss.print();
}
}
class Singleton
{
private Singleton(){}; //构造方法私有化
private static Singleton s = new Singleton(); //可以在Singleton中自己声明一个s对象(声明本类对象)
public static Singleton getInstance()
{
return s; //这个方法是给外部提供一个静态方法获取对象实例
}
//上面,Singleton的设计方法就完成了
public void print()
{
System.out.println("测试方法");
}
}
/*
结果:
测试方法
测试方法
*/
因为s和ss都指向了Singleton类,而这个类是一个单例设计的类,所以s和ss指的是同一个内存地址,s==ss。
所以饿汉式是一上来就很饿,所以直接在类中先new明一个对象出来,这样就行了。(在类被加载后,对象被创建,到程序结束后释放;占用内存时间长,但效率高)
2、懒汉式
在第一次调用类的getInstance()时,对象被创建,到程序接受释放;占用内存时间虽短,但效率低(懒加载,延迟加载)。(建议用)
public class a
{
public static void main(String[] args)
{
Singleton s = Singleton.getInstance(); //先获取一个实例
s.print();
System.out.println();
Singleton ss = Singleton.getInstance(); //先获取一个实例
ss.print();
System.out.println(s == ss);
}
}
class Singleton
{
private Singleton(){}; //构造方法私有化
private static Singleton s; //可以在Singleton中自己声明一个s对象(声明本类对象)
public static Singleton getInstance()
{
if(s == null)
s = new Singleton();
return s; //这个方法是给外部提供一个静态方法获取对象实例
}
//上面,Singleton的设计方法就完成了
public void print()
{
System.out.println("测试方法");
}
}
不过上面的代码并不光只是懒汉式的所有代码,还有更高级的,我们说到多线程时再说。
在项目中为什么要使用单例,单例有什么好处?
1、在设计一些工具类的时候(通常工具类,只有功能方法,没有属性)。
2、工具类可能会被频繁使用——创建单例目的是为了节省重复创建对象所带来的内存消耗,从而提高效率。
3、可以使用构造方法私有化+静态方法来代替单例。但是构造方法私有化+静态方法占内存较多,单例会好点。