写到这里,突然发现自己对单件这个词的理解并不深入,所以到网上找了一下单件的定义以及单件的应用场景。
网上也没有对单件这个词的解释,更多的是对单件模式的理解,那我们姑且根据对单件模式的理解将单件理解为在整个工程中只能被实例化一次并且在整个项目中只能有一个实例化的对象的类(无非就是在普通类前面加上了一系列的限制来表示它的特殊性而已,嘿嘿嘿)。单件模式你可能并没有听说过这个模式,但是它的应用在生活中确实随时可见的。
也许从定义上你会觉得这样一个类似乎是和面向对象的定义是相悖的,我们在编程中希望多态性还来不及,又怎么会希望有一个类在整个生命周期中只被实例化一次呢?
话不能说的这么绝对,看看这种情况:系统的注册表,在多用户的系统中如果有多个用户拥有一个系统注册表对象而对其进行操作,那很可能会造成整个系统的错误......
怎么保证一个类在整个项目中当需要用到时被实例化一次,后面再次要被用到时只需要返回之前已经创建的对象,而当在此次项目的运行中并不需要用到它的时候并不需要对他进行实例化呢?
我们来一步一步进行思考,将对象实例化,无非还是用new关键字来创建一个对象,创建对象的时候就是调用了一次类的构造函数,那能不能通过限制对构造函数的访问来达到只创建一个对象的目的呢?自然而然想到Java中的访问控制修饰符,希望你还没有忘,我们来简单回顾一下:用public修饰的变量或者方法,对所有类都是可见的,用private修饰的变量或者方法,仅对本类可见,用protect修饰的类对本类和子类可见,而缺省不适用任何修饰符修饰时对对象所在的同一个包中的所有类是可见的。
那我们如果只想在全局范围中保证类只被实例化一次,自然是将构造函数的访问控制修饰符设置为private貌似更能达到我们的目的,这样虽然看起来怪怪的,貌似之前从来没有想过要将一个类的构造函数设置为私有的,那岂不是只有该类的对象能够创建一个对象了?那要怎么得到该类的一个对象来调用该类的构造函数从而得到一个该类的对象呢?
这无疑有点“鸡生蛋,蛋生鸡......”问题的意味了。再深入思考一下,什么情况下我们不需要该类的一个对象便能调用该类的构造函数得到一个实例化的对象呢?对!static!!!!,在该类中保留一个public的getInstence()的方法,并且将这个方法设置为类方法,只用类名就能调用该方法得到一个对象的实例了(前提是在该类中应该保留一个自身类型的成员变量,才能在static getInstence()方法中返回一个这个类型的对象),在getInstence()方法中我们要做一个判断,当是该对象在此时刻还未创建时才创建一个该类型的对象,而当已经有该类型的对象之前被创建时,直接返回该对象即可。
也许你已经知道我接下来要说什么了,在static方法中使用的变量也应该是static的。那么上述的该类中此类型的成员变量应该使用static来修饰!!
光说肯定是越来越糊涂。我们来尝试写一下刚才的推理过程:
public Singleton{
private static Singleton s; //静态同类型的成员变量
private Singleton(){} //私有构造函数
//获得静态对象的方法,该方法应是静态方法,并且应是public的,提供一个创建对象的公共接口
public static Singleton getInstence(){
if(s==null)
s=new Singleton();
else
return s;
}
在具有多个类加载器的应用情景下需要注意,还是可以获得多个实例化对象的,理论上有n个类加载器,就有n个实例化对象,因为静态方法和静态对象是随类加载器创建而创建的。
单件模式常常被用在管理公共的共享资源,例如数据库连接池或者线程池中被使用。
单件模式可能是最简单的一个模式了,下面给出单件模式的定义:
单件模式确保了一个类只有一个实例,并提供一个全局访问点。